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