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;
18
19import static com.google.common.truth.Truth.assertThat;
20import static java.util.Arrays.asList;
21
22import com.google.common.annotations.GwtCompatible;
23import com.google.common.annotations.GwtIncompatible;
24import com.google.common.collect.testing.ListTestSuiteBuilder;
25import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
26import com.google.common.collect.testing.features.CollectionFeature;
27import com.google.common.collect.testing.features.CollectionSize;
28import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetAsListGenerator;
29import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetCopyOfGenerator;
30import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetDescendingAsListGenerator;
31import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetDescendingGenerator;
32import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitComparator;
33import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitSuperclassComparatorGenerator;
34import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetReversedOrderGenerator;
35import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetAsListGenerator;
36import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetUnhashableGenerator;
37import com.google.common.collect.testing.testers.SetHashCodeTester;
38import com.google.common.testing.NullPointerTester;
39import com.google.common.testing.SerializableTester;
40
41import junit.framework.Test;
42import junit.framework.TestSuite;
43
44import java.util.Arrays;
45import java.util.Collection;
46import java.util.Collections;
47import java.util.Comparator;
48import java.util.Iterator;
49import java.util.NoSuchElementException;
50import java.util.Set;
51import java.util.SortedSet;
52import java.util.TreeSet;
53
54/**
55 * Unit tests for {@link ImmutableSortedSet}.
56 *
57 * @author Jared Levy
58 */
59@GwtCompatible(emulated = true)
60public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
61
62  @GwtIncompatible("suite")
63  public static Test suite() {
64    TestSuite suite = new TestSuite();
65
66    suite.addTest(NavigableSetTestSuiteBuilder.using(
67        new ImmutableSortedSetCopyOfGenerator())
68        .named(ImmutableSortedSetTest.class.getName())
69        .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
70            CollectionFeature.SERIALIZABLE,
71            CollectionFeature.ALLOWS_NULL_QUERIES)
72            .createTestSuite());
73
74    suite.addTest(NavigableSetTestSuiteBuilder.using(
75        new ImmutableSortedSetExplicitComparator())
76        .named(ImmutableSortedSetTest.class.getName()
77            + ", explicit comparator, vararg")
78            .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
79                CollectionFeature.SERIALIZABLE,
80                CollectionFeature.ALLOWS_NULL_QUERIES)
81                .createTestSuite());
82
83    suite.addTest(NavigableSetTestSuiteBuilder.using(
84        new ImmutableSortedSetExplicitSuperclassComparatorGenerator())
85        .named(ImmutableSortedSetTest.class.getName()
86            + ", explicit superclass comparator, iterable")
87            .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
88                CollectionFeature.SERIALIZABLE,
89                CollectionFeature.ALLOWS_NULL_QUERIES)
90                .createTestSuite());
91
92    suite.addTest(NavigableSetTestSuiteBuilder.using(
93        new ImmutableSortedSetReversedOrderGenerator())
94        .named(ImmutableSortedSetTest.class.getName()
95            + ", reverseOrder, iterator")
96            .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
97                CollectionFeature.SERIALIZABLE,
98                CollectionFeature.ALLOWS_NULL_QUERIES)
99                .createTestSuite());
100
101    suite.addTest(NavigableSetTestSuiteBuilder.using(
102        new ImmutableSortedSetUnhashableGenerator())
103        .suppressing(SetHashCodeTester.getHashCodeMethods())
104        .named(ImmutableSortedSetTest.class.getName() + ", unhashable")
105        .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
106            CollectionFeature.ALLOWS_NULL_QUERIES)
107            .createTestSuite());
108
109    suite.addTest(NavigableSetTestSuiteBuilder.using(
110        new ImmutableSortedSetDescendingGenerator())
111        .named(ImmutableSortedSetTest.class.getName() + ", descending")
112        .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
113            CollectionFeature.SERIALIZABLE,
114            CollectionFeature.ALLOWS_NULL_QUERIES)
115            .createTestSuite());
116
117    suite.addTest(ListTestSuiteBuilder.using(
118        new ImmutableSortedSetAsListGenerator())
119        .named("ImmutableSortedSet.asList")
120        .withFeatures(CollectionSize.ANY,
121            CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
122            CollectionFeature.SERIALIZABLE,
123            CollectionFeature.ALLOWS_NULL_QUERIES)
124            .createTestSuite());
125
126    suite.addTest(ListTestSuiteBuilder.using(
127        new ImmutableSortedSetSubsetAsListGenerator())
128        .named("ImmutableSortedSet.subSet.asList")
129        .withFeatures(CollectionSize.ANY,
130            CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
131            CollectionFeature.SERIALIZABLE,
132            CollectionFeature.ALLOWS_NULL_QUERIES)
133            .createTestSuite());
134
135    suite.addTest(ListTestSuiteBuilder.using(
136        new ImmutableSortedSetDescendingAsListGenerator())
137        .named("ImmutableSortedSet.descendingSet.asList")
138        .withFeatures(CollectionSize.ANY,
139            CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
140            CollectionFeature.SERIALIZABLE,
141            CollectionFeature.ALLOWS_NULL_QUERIES)
142            .createTestSuite());
143
144    suite.addTestSuite(ImmutableSortedSetTest.class);
145
146    return suite;
147  }
148
149  // enum singleton pattern
150  private enum StringLengthComparator implements Comparator<String> {
151    INSTANCE;
152
153    @Override
154    public int compare(String a, String b) {
155      return a.length() - b.length();
156    }
157  }
158
159  private static final Comparator<String> STRING_LENGTH
160      = StringLengthComparator.INSTANCE;
161
162  @Override protected SortedSet<String> of() {
163    return ImmutableSortedSet.of();
164  }
165
166  @Override protected SortedSet<String> of(String e) {
167    return ImmutableSortedSet.of(e);
168  }
169
170  @Override protected SortedSet<String> of(String e1, String e2) {
171    return ImmutableSortedSet.of(e1, e2);
172  }
173
174  @Override protected SortedSet<String> of(String e1, String e2, String e3) {
175    return ImmutableSortedSet.of(e1, e2, e3);
176  }
177
178  @Override protected SortedSet<String> of(
179      String e1, String e2, String e3, String e4) {
180    return ImmutableSortedSet.of(e1, e2, e3, e4);
181  }
182
183  @Override protected SortedSet<String> of(
184      String e1, String e2, String e3, String e4, String e5) {
185    return ImmutableSortedSet.of(e1, e2, e3, e4, e5);
186  }
187
188  @Override protected SortedSet<String> of(String e1, String e2, String e3,
189      String e4, String e5, String e6, String... rest) {
190    return ImmutableSortedSet.of(e1, e2, e3, e4, e5, e6, rest);
191  }
192
193  @Override protected SortedSet<String> copyOf(String[] elements) {
194    return ImmutableSortedSet.copyOf(elements);
195  }
196
197  @Override protected SortedSet<String> copyOf(Collection<String> elements) {
198    return ImmutableSortedSet.copyOf(elements);
199  }
200
201  @Override protected SortedSet<String> copyOf(Iterable<String> elements) {
202    return ImmutableSortedSet.copyOf(elements);
203  }
204
205  @Override protected SortedSet<String> copyOf(Iterator<String> elements) {
206    return ImmutableSortedSet.copyOf(elements);
207  }
208
209  @GwtIncompatible("NullPointerTester")
210  public void testNullPointers() {
211    new NullPointerTester().testAllPublicStaticMethods(ImmutableSortedSet.class);
212  }
213
214  public void testEmpty_comparator() {
215    SortedSet<String> set = of();
216    assertSame(Ordering.natural(), set.comparator());
217  }
218
219  public void testEmpty_headSet() {
220    SortedSet<String> set = of();
221    assertSame(set, set.headSet("c"));
222  }
223
224  public void testEmpty_tailSet() {
225    SortedSet<String> set = of();
226    assertSame(set, set.tailSet("f"));
227  }
228
229  public void testEmpty_subSet() {
230    SortedSet<String> set = of();
231    assertSame(set, set.subSet("c", "f"));
232  }
233
234  public void testEmpty_first() {
235    SortedSet<String> set = of();
236    try {
237      set.first();
238      fail();
239    } catch (NoSuchElementException expected) {
240    }
241  }
242
243  public void testEmpty_last() {
244    SortedSet<String> set = of();
245    try {
246      set.last();
247      fail();
248    } catch (NoSuchElementException expected) {
249    }
250  }
251
252  @GwtIncompatible("SerializableTester")
253  public void testEmpty_serialization() {
254    SortedSet<String> set = of();
255    SortedSet<String> copy = SerializableTester.reserialize(set);
256    assertSame(set, copy);
257  }
258
259  public void testSingle_comparator() {
260    SortedSet<String> set = of("e");
261    assertSame(Ordering.natural(), set.comparator());
262  }
263
264  public void testSingle_headSet() {
265    SortedSet<String> set = of("e");
266    assertTrue(set.headSet("g") instanceof ImmutableSortedSet);
267    assertThat(set.headSet("g")).has().item("e");
268    assertSame(of(), set.headSet("c"));
269    assertSame(of(), set.headSet("e"));
270  }
271
272  public void testSingle_tailSet() {
273    SortedSet<String> set = of("e");
274    assertTrue(set.tailSet("c") instanceof ImmutableSortedSet);
275    assertThat(set.tailSet("c")).has().item("e");
276    assertThat(set.tailSet("e")).has().item("e");
277    assertSame(of(), set.tailSet("g"));
278  }
279
280  public void testSingle_subSet() {
281    SortedSet<String> set = of("e");
282    assertTrue(set.subSet("c", "g") instanceof ImmutableSortedSet);
283    assertThat(set.subSet("c", "g")).has().item("e");
284    assertThat(set.subSet("e", "g")).has().item("e");
285    assertSame(of(), set.subSet("f", "g"));
286    assertSame(of(), set.subSet("c", "e"));
287    assertSame(of(), set.subSet("c", "d"));
288  }
289
290  public void testSingle_first() {
291    SortedSet<String> set = of("e");
292    assertEquals("e", set.first());
293  }
294
295  public void testSingle_last() {
296    SortedSet<String> set = of("e");
297    assertEquals("e", set.last());
298  }
299
300  @GwtIncompatible("SerializableTester")
301  public void testSingle_serialization() {
302    SortedSet<String> set = of("e");
303    SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
304    assertEquals(set.comparator(), copy.comparator());
305  }
306
307  public void testOf_ordering() {
308    SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
309    assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
310  }
311
312  /*
313   * Tests that we workaround GWT bug #3621 (or that it is already fixed).
314   *
315   * A call to of() with a parameter that is not a plain Object[] (here,
316   * Interface[]) creates a RegularImmutableSortedSet backed by an array of that
317   * type. Later, RegularImmutableSortedSet.toArray() calls System.arraycopy()
318   * to copy from that array to the destination array. This would be fine, but
319   * GWT has a bug: It refuses to copy from an E[] to an Object[] when E is an
320   * interface type.
321   */
322  // TODO: test other collections for this problem
323  public void testOf_gwtArraycopyBug() {
324    /*
325     * The test requires:
326     *
327     * 1) An interface I extending Comparable<I> so that the created array is of
328     * an interface type. 2) An instance of a class implementing that interface
329     * so that we can pass non-null instances of the interface.
330     *
331     * (Currently it's safe to pass instances for which compareTo() always
332     * returns 0, but if we had a SingletonImmutableSortedSet, this might no
333     * longer be the case.)
334     *
335     * javax.naming.Name and java.util.concurrent.Delayed might work, but
336     * they're fairly obscure, we've invented our own interface and class.
337     */
338    Interface a = new Impl();
339    Interface b = new Impl();
340    ImmutableSortedSet<Interface> set = ImmutableSortedSet.of(a, b);
341    set.toArray();
342    set.toArray(new Object[2]);
343  }
344
345  interface Interface extends Comparable<Interface> {
346  }
347  static class Impl implements Interface {
348    static int nextId;
349    Integer id = nextId++;
350
351    @Override public int compareTo(Interface other) {
352      return id.compareTo(((Impl) other).id);
353    }
354  }
355
356  public void testOf_ordering_dupes() {
357    SortedSet<String> set = of("e", "a", "e", "f", "b", "b", "d", "a", "c");
358    assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
359  }
360
361  public void testOf_comparator() {
362    SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
363    assertSame(Ordering.natural(), set.comparator());
364  }
365
366  public void testOf_headSet() {
367    SortedSet<String> set = of("e", "f", "b", "d", "c");
368    assertTrue(set.headSet("e") instanceof ImmutableSortedSet);
369    assertThat(set.headSet("e")).has().exactly("b", "c", "d").inOrder();
370    assertThat(set.headSet("g")).has().exactly("b", "c", "d", "e", "f").inOrder();
371    assertSame(of(), set.headSet("a"));
372    assertSame(of(), set.headSet("b"));
373  }
374
375  public void testOf_tailSet() {
376    SortedSet<String> set = of("e", "f", "b", "d", "c");
377    assertTrue(set.tailSet("e") instanceof ImmutableSortedSet);
378    assertThat(set.tailSet("e")).has().exactly("e", "f").inOrder();
379    assertThat(set.tailSet("a")).has().exactly("b", "c", "d", "e", "f").inOrder();
380    assertSame(of(), set.tailSet("g"));
381  }
382
383  public void testOf_subSet() {
384    SortedSet<String> set = of("e", "f", "b", "d", "c");
385    assertTrue(set.subSet("c", "e") instanceof ImmutableSortedSet);
386    assertThat(set.subSet("c", "e")).has().exactly("c", "d").inOrder();
387    assertThat(set.subSet("a", "g")).has().exactly("b", "c", "d", "e", "f").inOrder();
388    assertSame(of(), set.subSet("a", "b"));
389    assertSame(of(), set.subSet("g", "h"));
390    assertSame(of(), set.subSet("c", "c"));
391    try {
392      set.subSet("e", "c");
393      fail();
394    } catch (IllegalArgumentException expected) {
395    }
396  }
397
398  @GwtIncompatible("SerializableTester")
399  public void testOf_subSetSerialization() {
400    SortedSet<String> set = of("e", "f", "b", "d", "c");
401    SerializableTester.reserializeAndAssert(set.subSet("c", "e"));
402  }
403
404  public void testOf_first() {
405    SortedSet<String> set = of("e", "f", "b", "d", "c");
406    assertEquals("b", set.first());
407  }
408
409  public void testOf_last() {
410    SortedSet<String> set = of("e", "f", "b", "d", "c");
411    assertEquals("f", set.last());
412  }
413
414  @GwtIncompatible("SerializableTester")
415  public void testOf_serialization() {
416    SortedSet<String> set = of("e", "f", "b", "d", "c");
417    SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
418    assertTrue(Iterables.elementsEqual(set, copy));
419    assertEquals(set.comparator(), copy.comparator());
420  }
421
422  /* "Explicit" indicates an explicit comparator. */
423
424  public void testExplicit_ordering() {
425    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
426        "in", "the", "quick", "jumped", "over", "a").build();
427    assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
428  }
429
430  public void testExplicit_ordering_dupes() {
431    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
432        "in", "the", "quick", "brown", "fox", "jumped",
433        "over", "a", "lazy", "dog").build();
434    assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
435  }
436
437  public void testExplicit_contains() {
438    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
439        "in", "the", "quick", "jumped", "over", "a").build();
440    assertTrue(set.contains("quick"));
441    assertTrue(set.contains("google"));
442    assertFalse(set.contains(""));
443    assertFalse(set.contains("california"));
444    assertFalse(set.contains(null));
445  }
446
447  public void testExplicit_containsMismatchedTypes() {
448    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
449        "in", "the", "quick", "jumped", "over", "a").build();
450    assertFalse(set.contains(3.7));
451  }
452
453  public void testExplicit_comparator() {
454    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
455        "in", "the", "quick", "jumped", "over", "a").build();
456    assertSame(STRING_LENGTH, set.comparator());
457  }
458
459  public void testExplicit_headSet() {
460    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
461        "in", "the", "quick", "jumped", "over", "a").build();
462    assertTrue(set.headSet("a") instanceof ImmutableSortedSet);
463    assertTrue(set.headSet("fish") instanceof ImmutableSortedSet);
464    assertThat(set.headSet("fish")).has().exactly("a", "in", "the").inOrder();
465    assertThat(set.headSet("california")).has()
466        .exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
467    assertTrue(set.headSet("a").isEmpty());
468    assertTrue(set.headSet("").isEmpty());
469  }
470
471  public void testExplicit_tailSet() {
472    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
473        "in", "the", "quick", "jumped", "over", "a").build();
474    assertTrue(set.tailSet("california") instanceof ImmutableSortedSet);
475    assertTrue(set.tailSet("fish") instanceof ImmutableSortedSet);
476    assertThat(set.tailSet("fish")).has().exactly("over", "quick", "jumped").inOrder();
477    assertThat(
478        set.tailSet("a")).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
479    assertTrue(set.tailSet("california").isEmpty());
480  }
481
482  public void testExplicit_subSet() {
483    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
484        "in", "the", "quick", "jumped", "over", "a").build();
485    assertTrue(set.subSet("the", "quick") instanceof ImmutableSortedSet);
486    assertTrue(set.subSet("", "b") instanceof ImmutableSortedSet);
487    assertThat(set.subSet("the", "quick")).has().exactly("the", "over").inOrder();
488    assertThat(set.subSet("a", "california"))
489        .has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
490    assertTrue(set.subSet("", "b").isEmpty());
491    assertTrue(set.subSet("vermont", "california").isEmpty());
492    assertTrue(set.subSet("aaa", "zzz").isEmpty());
493    try {
494      set.subSet("quick", "the");
495      fail();
496    } catch (IllegalArgumentException expected) {
497    }
498  }
499
500  public void testExplicit_first() {
501    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
502        "in", "the", "quick", "jumped", "over", "a").build();
503    assertEquals("a", set.first());
504  }
505
506  public void testExplicit_last() {
507    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
508        "in", "the", "quick", "jumped", "over", "a").build();
509    assertEquals("jumped", set.last());
510  }
511
512  @GwtIncompatible("SerializableTester")
513  public void testExplicitEmpty_serialization() {
514    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).build();
515    SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
516    assertTrue(set.isEmpty());
517    assertTrue(copy.isEmpty());
518    assertSame(set.comparator(), copy.comparator());
519  }
520
521  @GwtIncompatible("SerializableTester")
522  public void testExplicit_serialization() {
523    SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
524        "in", "the", "quick", "jumped", "over", "a").build();
525    SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
526    assertTrue(Iterables.elementsEqual(set, copy));
527    assertSame(set.comparator(), copy.comparator());
528  }
529
530  public void testCopyOf_ordering() {
531    SortedSet<String> set =
532        copyOf(asList("e", "a", "f", "b", "d", "c"));
533    assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
534  }
535
536  public void testCopyOf_ordering_dupes() {
537    SortedSet<String> set =
538        copyOf(asList("e", "a", "e", "f", "b", "b", "d", "a", "c"));
539    assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
540  }
541
542  public void testCopyOf_subSet() {
543    SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
544    SortedSet<String> subset = set.subSet("c", "e");
545    SortedSet<String> copy = copyOf(subset);
546    assertEquals(subset, copy);
547  }
548
549  public void testCopyOf_headSet() {
550    SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
551    SortedSet<String> headset = set.headSet("d");
552    SortedSet<String> copy = copyOf(headset);
553    assertEquals(headset, copy);
554  }
555
556  public void testCopyOf_tailSet() {
557    SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
558    SortedSet<String> tailset = set.tailSet("d");
559    SortedSet<String> copy = copyOf(tailset);
560    assertEquals(tailset, copy);
561  }
562
563  public void testCopyOf_comparator() {
564    SortedSet<String> set = copyOf(asList("e", "a", "f", "b", "d", "c"));
565    assertSame(Ordering.natural(), set.comparator());
566  }
567
568  public void testCopyOf_iterator_ordering() {
569    SortedSet<String> set = copyOf(asIterator("e", "a", "f", "b", "d", "c"));
570    assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
571  }
572
573  public void testCopyOf_iterator_ordering_dupes() {
574    SortedSet<String> set =
575        copyOf(asIterator("e", "a", "e", "f", "b", "b", "d", "a", "c"));
576    assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
577  }
578
579  public void testCopyOf_iterator_comparator() {
580    SortedSet<String> set = copyOf(asIterator("e", "a", "f", "b", "d", "c"));
581    assertSame(Ordering.natural(), set.comparator());
582  }
583
584  public void testCopyOf_sortedSet_ordering() {
585    SortedSet<String> set =
586        copyOf(Sets.newTreeSet(asList("e", "a", "f", "b", "d", "c")));
587    assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
588  }
589
590  public void testCopyOf_sortedSet_comparator() {
591    SortedSet<String> set = copyOf(Sets.<String>newTreeSet());
592    assertSame(Ordering.natural(), set.comparator());
593  }
594
595  public void testCopyOfExplicit_ordering() {
596    SortedSet<String> set =
597        ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
598            "in", "the", "quick", "jumped", "over", "a"));
599    assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
600  }
601
602  public void testCopyOfExplicit_ordering_dupes() {
603    SortedSet<String> set =
604        ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
605            "in", "the", "quick", "brown", "fox", "jumped", "over", "a",
606            "lazy", "dog"));
607    assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
608  }
609
610  public void testCopyOfExplicit_comparator() {
611    SortedSet<String> set =
612        ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
613            "in", "the", "quick", "jumped", "over", "a"));
614    assertSame(STRING_LENGTH, set.comparator());
615  }
616
617  public void testCopyOfExplicit_iterator_ordering() {
618    SortedSet<String> set =
619        ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
620            "in", "the", "quick", "jumped", "over", "a"));
621    assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
622  }
623
624  public void testCopyOfExplicit_iterator_ordering_dupes() {
625    SortedSet<String> set =
626        ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
627            "in", "the", "quick", "brown", "fox", "jumped", "over", "a",
628            "lazy", "dog"));
629    assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
630  }
631
632  public void testCopyOfExplicit_iterator_comparator() {
633    SortedSet<String> set =
634        ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
635            "in", "the", "quick", "jumped", "over", "a"));
636    assertSame(STRING_LENGTH, set.comparator());
637  }
638
639  public void testCopyOf_sortedSetIterable() {
640    SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
641    Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
642    SortedSet<String> set = copyOf(input);
643    assertThat(set).has().exactly("a", "in", "jumped", "over", "quick", "the").inOrder();
644  }
645
646  public void testCopyOfSorted_natural_ordering() {
647    SortedSet<String> input = Sets.newTreeSet(
648        asList("in", "the", "quick", "jumped", "over", "a"));
649    SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
650    assertThat(set).has().exactly("a", "in", "jumped", "over", "quick", "the").inOrder();
651  }
652
653  public void testCopyOfSorted_natural_comparator() {
654    SortedSet<String> input =
655        Sets.newTreeSet(asList("in", "the", "quick", "jumped", "over", "a"));
656    SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
657    assertSame(Ordering.natural(), set.comparator());
658  }
659
660  public void testCopyOfSorted_explicit_ordering() {
661    SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
662    Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
663    SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
664    assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
665    assertSame(STRING_LENGTH, set.comparator());
666  }
667
668  public void testEquals_bothDefaultOrdering() {
669    SortedSet<String> set = of("a", "b", "c");
670    assertEquals(set, Sets.newTreeSet(asList("a", "b", "c")));
671    assertEquals(Sets.newTreeSet(asList("a", "b", "c")), set);
672    assertFalse(set.equals(Sets.newTreeSet(asList("a", "b", "d"))));
673    assertFalse(Sets.newTreeSet(asList("a", "b", "d")).equals(set));
674    assertFalse(set.equals(Sets.newHashSet(4, 5, 6)));
675    assertFalse(Sets.newHashSet(4, 5, 6).equals(set));
676  }
677
678  public void testEquals_bothExplicitOrdering() {
679    SortedSet<String> set = of("in", "the", "a");
680    assertEquals(Sets.newTreeSet(asList("in", "the", "a")), set);
681    assertFalse(set.equals(Sets.newTreeSet(asList("in", "the", "house"))));
682    assertFalse(Sets.newTreeSet(asList("in", "the", "house")).equals(set));
683    assertFalse(set.equals(Sets.newHashSet(4, 5, 6)));
684    assertFalse(Sets.newHashSet(4, 5, 6).equals(set));
685
686    Set<String> complex = Sets.newTreeSet(STRING_LENGTH);
687    Collections.addAll(complex, "in", "the", "a");
688    assertEquals(set, complex);
689  }
690
691  public void testEquals_bothDefaultOrdering_StringVsInt() {
692    SortedSet<String> set = of("a", "b", "c");
693    assertFalse(set.equals(Sets.newTreeSet(asList(4, 5, 6))));
694    assertNotEqualLenient(Sets.newTreeSet(asList(4, 5, 6)), set);
695  }
696
697  public void testEquals_bothExplicitOrdering_StringVsInt() {
698    SortedSet<String> set = of("in", "the", "a");
699    assertFalse(set.equals(Sets.newTreeSet(asList(4, 5, 6))));
700    assertNotEqualLenient(Sets.newTreeSet(asList(4, 5, 6)), set);
701  }
702
703  public void testContainsAll_notSortedSet() {
704    SortedSet<String> set = of("a", "b", "f");
705    assertTrue(set.containsAll(Collections.emptyList()));
706    assertTrue(set.containsAll(asList("b")));
707    assertTrue(set.containsAll(asList("b", "b")));
708    assertTrue(set.containsAll(asList("b", "f")));
709    assertTrue(set.containsAll(asList("b", "f", "a")));
710    assertFalse(set.containsAll(asList("d")));
711    assertFalse(set.containsAll(asList("z")));
712    assertFalse(set.containsAll(asList("b", "d")));
713    assertFalse(set.containsAll(asList("f", "d", "a")));
714  }
715
716  public void testContainsAll_sameComparator() {
717    SortedSet<String> set = of("a", "b", "f");
718    assertTrue(set.containsAll(Sets.newTreeSet()));
719    assertTrue(set.containsAll(Sets.newTreeSet(asList("b"))));
720    assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "f"))));
721    assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "b", "f"))));
722    assertFalse(set.containsAll(Sets.newTreeSet(asList("d"))));
723    assertFalse(set.containsAll(Sets.newTreeSet(asList("z"))));
724    assertFalse(set.containsAll(Sets.newTreeSet(asList("b", "d"))));
725    assertFalse(set.containsAll(Sets.newTreeSet(asList("f", "d", "a"))));
726  }
727
728  public void testContainsAll_sameComparator_StringVsInt() {
729    SortedSet<String> set = of("a", "b", "f");
730    SortedSet<Integer> unexpected = Sets.newTreeSet(Ordering.natural());
731    unexpected.addAll(asList(1, 2, 3));
732    assertFalse(set.containsAll(unexpected));
733  }
734
735  public void testContainsAll_differentComparator() {
736    Comparator<Comparable<?>> comparator = Collections.reverseOrder();
737    SortedSet<String> set = new ImmutableSortedSet.Builder<String>(comparator)
738        .add("a", "b", "f").build();
739    assertTrue(set.containsAll(Sets.newTreeSet()));
740    assertTrue(set.containsAll(Sets.newTreeSet(asList("b"))));
741    assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "f"))));
742    assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "b", "f"))));
743    assertFalse(set.containsAll(Sets.newTreeSet(asList("d"))));
744    assertFalse(set.containsAll(Sets.newTreeSet(asList("z"))));
745    assertFalse(set.containsAll(Sets.newTreeSet(asList("b", "d"))));
746    assertFalse(set.containsAll(Sets.newTreeSet(asList("f", "d", "a"))));
747  }
748
749  @GwtIncompatible("SerializableTester")
750  public void testDifferentComparator_serialization() {
751    // don't use Collections.reverseOrder(); it didn't reserialize to the same instance in JDK5
752    Comparator<Comparable<?>> comparator = Ordering.natural().reverse();
753    SortedSet<String> set = new ImmutableSortedSet.Builder<String>(comparator)
754        .add("a", "b", "c").build();
755    SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
756    assertTrue(Iterables.elementsEqual(set, copy));
757    assertEquals(set.comparator(), copy.comparator());
758  }
759
760  public void testReverseOrder() {
761    SortedSet<String> set = ImmutableSortedSet.<String>reverseOrder()
762        .add("a", "b", "c").build();
763    assertThat(set).has().exactly("c", "b", "a").inOrder();
764    assertEquals(Ordering.natural().reverse(), set.comparator());
765  }
766
767  private static final Comparator<Object> TO_STRING
768      = new Comparator<Object>() {
769          @Override
770          public int compare(Object o1, Object o2) {
771            return o1.toString().compareTo(o2.toString());
772          }
773        };
774
775  public void testSupertypeComparator() {
776    SortedSet<Integer> set = new ImmutableSortedSet.Builder<Integer>(TO_STRING)
777        .add(3, 12, 101, 44).build();
778    assertThat(set).has().exactly(101, 12, 3, 44).inOrder();
779  }
780
781  public void testSupertypeComparatorSubtypeElements() {
782    SortedSet<Number> set = new ImmutableSortedSet.Builder<Number>(TO_STRING)
783        .add(3, 12, 101, 44).build();
784    assertThat(set).has().exactly(101, 12, 3, 44).inOrder();
785  }
786
787  @Override <E extends Comparable<E>> ImmutableSortedSet.Builder<E> builder() {
788    return ImmutableSortedSet.naturalOrder();
789  }
790
791  @Override int getComplexBuilderSetLastElement() {
792    return 0x00FFFFFF;
793  }
794
795  public void testLegacyComparable_of() {
796    ImmutableSortedSet<LegacyComparable> set0 = ImmutableSortedSet.of();
797
798    @SuppressWarnings("unchecked") // using a legacy comparable
799    ImmutableSortedSet<LegacyComparable> set1 = ImmutableSortedSet.of(
800        LegacyComparable.Z);
801
802    @SuppressWarnings("unchecked") // using a legacy comparable
803    ImmutableSortedSet<LegacyComparable> set2 = ImmutableSortedSet.of(
804        LegacyComparable.Z, LegacyComparable.Y);
805  }
806
807  public void testLegacyComparable_copyOf_collection() {
808    ImmutableSortedSet<LegacyComparable> set
809        = ImmutableSortedSet.copyOf(LegacyComparable.VALUES_BACKWARD);
810    assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_FORWARD, set));
811  }
812
813  public void testLegacyComparable_copyOf_iterator() {
814    ImmutableSortedSet<LegacyComparable> set = ImmutableSortedSet.copyOf(
815        LegacyComparable.VALUES_BACKWARD.iterator());
816    assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_FORWARD, set));
817  }
818
819  public void testLegacyComparable_builder_natural() {
820    @SuppressWarnings("unchecked")
821    // Note: IntelliJ wrongly reports an error for this statement
822    ImmutableSortedSet.Builder<LegacyComparable> builder
823        = ImmutableSortedSet.<LegacyComparable>naturalOrder();
824
825    builder.addAll(LegacyComparable.VALUES_BACKWARD);
826    builder.add(LegacyComparable.X);
827    builder.add(LegacyComparable.Y, LegacyComparable.Z);
828
829    ImmutableSortedSet<LegacyComparable> set = builder.build();
830    assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_FORWARD, set));
831  }
832
833  public void testLegacyComparable_builder_reverse() {
834    @SuppressWarnings("unchecked")
835    // Note: IntelliJ wrongly reports an error for this statement
836    ImmutableSortedSet.Builder<LegacyComparable> builder
837        = ImmutableSortedSet.<LegacyComparable>reverseOrder();
838
839    builder.addAll(LegacyComparable.VALUES_FORWARD);
840    builder.add(LegacyComparable.X);
841    builder.add(LegacyComparable.Y, LegacyComparable.Z);
842
843    ImmutableSortedSet<LegacyComparable> set = builder.build();
844    assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_BACKWARD, set));
845  }
846
847  @SuppressWarnings({"deprecation", "static-access"})
848  public void testBuilderMethod() {
849    try {
850      ImmutableSortedSet.builder();
851      fail();
852    } catch (UnsupportedOperationException expected) {
853    }
854  }
855
856  public void testAsList() {
857    ImmutableSet<String> set = ImmutableSortedSet.of("a", "e", "i", "o", "u");
858    ImmutableList<String> list = set.asList();
859    assertEquals(ImmutableList.of("a", "e", "i", "o", "u"), list);
860    assertSame(list, ImmutableList.copyOf(set));
861  }
862
863  @GwtIncompatible("SerializableTester, ImmutableSortedAsList")
864  public void testAsListReturnTypeAndSerialization() {
865    ImmutableSet<String> set = ImmutableSortedSet.of("a", "e", "i", "o", "u");
866    ImmutableList<String> list = set.asList();
867    assertTrue(list instanceof ImmutableSortedAsList);
868    ImmutableList<String> copy = SerializableTester.reserializeAndAssert(list);
869    assertTrue(copy instanceof ImmutableSortedAsList);
870  }
871
872  public void testSubsetAsList() {
873    ImmutableSet<String> set
874        = ImmutableSortedSet.of("a", "e", "i", "o", "u").subSet("c", "r");
875    ImmutableList<String> list = set.asList();
876    assertEquals(ImmutableList.of("e", "i", "o"), list);
877    assertEquals(list, ImmutableList.copyOf(set));
878  }
879
880  @GwtIncompatible("SerializableTester, ImmutableSortedAsList")
881  public void testSubsetAsListReturnTypeAndSerialization() {
882    ImmutableSet<String> set
883        = ImmutableSortedSet.of("a", "e", "i", "o", "u").subSet("c", "r");
884    ImmutableList<String> list = set.asList();
885    assertTrue(list instanceof ImmutableSortedAsList);
886    ImmutableList<String> copy = SerializableTester.reserializeAndAssert(list);
887    assertTrue(copy instanceof ImmutableSortedAsList);
888  }
889
890  public void testAsListInconsistentComprator() {
891    ImmutableSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
892        "in", "the", "quick", "jumped", "over", "a").build();
893    ImmutableList<String> list = set.asList();
894    assertTrue(list.contains("the"));
895    assertEquals(2, list.indexOf("the"));
896    assertEquals(2, list.lastIndexOf("the"));
897    assertFalse(list.contains("dog"));
898    assertEquals(-1, list.indexOf("dog"));
899    assertEquals(-1, list.lastIndexOf("dog"));
900    assertFalse(list.contains("chicken"));
901    assertEquals(-1, list.indexOf("chicken"));
902    assertEquals(-1, list.lastIndexOf("chicken"));
903  }
904
905  private static <E> Iterator<E> asIterator(E... elements) {
906    return asList(elements).iterator();
907  }
908
909  // In GWT, java.util.TreeSet throws ClassCastException when the comparator
910  // throws it, unlike JDK6.  Therefore, we accept ClassCastException as a
911  // valid result thrown by java.util.TreeSet#equals.
912  private static void assertNotEqualLenient(
913      TreeSet<?> unexpected, SortedSet<?> actual) {
914    try {
915      assertThat(actual).isNotEqualTo(unexpected);
916    } catch (ClassCastException accepted) {
917    }
918  }
919
920  public void testHeadSetInclusive() {
921    String[] strings = NUMBER_NAMES.toArray(new String[0]);
922    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
923    Arrays.sort(strings);
924    for (int i = 0; i < strings.length; i++) {
925      assertThat(set.headSet(strings[i], true))
926          .has().exactlyAs(sortedNumberNames(0, i + 1)).inOrder();
927    }
928  }
929
930  public void testHeadSetExclusive() {
931    String[] strings = NUMBER_NAMES.toArray(new String[0]);
932    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
933    Arrays.sort(strings);
934    for (int i = 0; i < strings.length; i++) {
935      assertThat(set.headSet(strings[i], false)).has().exactlyAs(
936          sortedNumberNames(0, i)).inOrder();
937    }
938  }
939
940  public void testTailSetInclusive() {
941    String[] strings = NUMBER_NAMES.toArray(new String[0]);
942    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
943    Arrays.sort(strings);
944    for (int i = 0; i < strings.length; i++) {
945      assertThat(set.tailSet(strings[i], true)).has().exactlyAs(
946          sortedNumberNames(i, strings.length)).inOrder();
947    }
948  }
949
950  public void testTailSetExclusive() {
951    String[] strings = NUMBER_NAMES.toArray(new String[0]);
952    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
953    Arrays.sort(strings);
954    for (int i = 0; i < strings.length; i++) {
955      assertThat(set.tailSet(strings[i], false)).has().exactlyAs(
956          sortedNumberNames(i + 1, strings.length)).inOrder();
957    }
958  }
959
960  public void testSubSetExclusiveExclusive() {
961    String[] strings = NUMBER_NAMES.toArray(new String[0]);
962    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
963    Arrays.sort(strings);
964    for (int i = 0; i < strings.length; i++) {
965      for (int j = i; j < strings.length; j++) {
966        assertThat(set.subSet(strings[i], false, strings[j], false))
967            .has().exactlyAs(sortedNumberNames(Math.min(i + 1, j), j)).inOrder();
968      }
969    }
970  }
971
972  public void testSubSetInclusiveExclusive() {
973    String[] strings = NUMBER_NAMES.toArray(new String[0]);
974    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
975    Arrays.sort(strings);
976    for (int i = 0; i < strings.length; i++) {
977      for (int j = i; j < strings.length; j++) {
978        assertThat(set.subSet(strings[i], true, strings[j], false))
979            .has().exactlyAs(sortedNumberNames(i, j)).inOrder();
980      }
981    }
982  }
983
984  public void testSubSetExclusiveInclusive() {
985    String[] strings = NUMBER_NAMES.toArray(new String[0]);
986    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
987    Arrays.sort(strings);
988    for (int i = 0; i < strings.length; i++) {
989      for (int j = i; j < strings.length; j++) {
990        assertThat(set.subSet(strings[i], false, strings[j], true))
991            .has().exactlyAs(sortedNumberNames(i + 1, j + 1)).inOrder();
992      }
993    }
994  }
995
996  public void testSubSetInclusiveInclusive() {
997    String[] strings = NUMBER_NAMES.toArray(new String[0]);
998    ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
999    Arrays.sort(strings);
1000    for (int i = 0; i < strings.length; i++) {
1001      for (int j = i; j < strings.length; j++) {
1002        assertThat(set.subSet(strings[i], true, strings[j], true))
1003            .has().exactlyAs(sortedNumberNames(i, j + 1)).inOrder();
1004      }
1005    }
1006  }
1007
1008  private static ImmutableList<String> sortedNumberNames(int i, int j) {
1009    return ImmutableList.copyOf(SORTED_NUMBER_NAMES.subList(i, j));
1010  }
1011
1012  private static final ImmutableList<String> NUMBER_NAMES =
1013      ImmutableList.of("one", "two", "three", "four", "five", "six", "seven");
1014
1015  private static final ImmutableList<String> SORTED_NUMBER_NAMES =
1016      Ordering.natural().immutableSortedCopy(NUMBER_NAMES);
1017
1018  private static class SelfComparableExample implements Comparable<SelfComparableExample> {
1019    @Override
1020    public int compareTo(SelfComparableExample o) {
1021      return 0;
1022    }
1023  }
1024
1025  public void testBuilderGenerics_SelfComparable() {
1026    ImmutableSortedSet.Builder<SelfComparableExample> natural = ImmutableSortedSet.naturalOrder();
1027    ImmutableSortedSet.Builder<SelfComparableExample> reverse = ImmutableSortedSet.reverseOrder();
1028  }
1029
1030  private static class SuperComparableExample extends SelfComparableExample {}
1031
1032  public void testBuilderGenerics_SuperComparable() {
1033    ImmutableSortedSet.Builder<SuperComparableExample> natural = ImmutableSortedSet.naturalOrder();
1034    ImmutableSortedSet.Builder<SuperComparableExample> reverse = ImmutableSortedSet.reverseOrder();
1035  }
1036}
1037