• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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.truth.Truth.assertThat;
20 
21 import com.google.common.annotations.GwtCompatible;
22 import com.google.common.annotations.GwtIncompatible;
23 import com.google.common.testing.SerializableTester;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.Comparator;
27 import java.util.Iterator;
28 import java.util.Map.Entry;
29 import java.util.SortedSet;
30 import junit.framework.TestCase;
31 import org.checkerframework.checker.nullness.qual.Nullable;
32 
33 /**
34  * Unit tests for {@code TreeMultimap} with explicit comparators.
35  *
36  * @author Jared Levy
37  */
38 @GwtCompatible(emulated = true)
39 public class TreeMultimapExplicitTest extends TestCase {
40 
41   /**
42    * Compare strings lengths, and if the lengths are equal compare the strings. A {@code null} is
43    * less than any non-null value.
44    */
45   private enum StringLength implements Comparator<@Nullable String> {
46     COMPARATOR;
47 
48     @Override
compare(@ullable String first, @Nullable String second)49     public int compare(@Nullable String first, @Nullable String second) {
50       if (first == second) {
51         return 0;
52       } else if (first == null) {
53         return -1;
54       } else if (second == null) {
55         return 1;
56       } else if (first.length() != second.length()) {
57         return first.length() - second.length();
58       } else {
59         return first.compareTo(second);
60       }
61     }
62   }
63 
64   /** Decreasing integer values. A {@code null} comes before any non-null value. */
65   private static final Comparator<Integer> DECREASING_INT_COMPARATOR =
66       Ordering.<Integer>natural().reverse().nullsFirst();
67 
create()68   private SetMultimap<String, Integer> create() {
69     return TreeMultimap.create(StringLength.COMPARATOR, DECREASING_INT_COMPARATOR);
70   }
71 
72   /** Create and populate a {@code TreeMultimap} with explicit comparators. */
createPopulate()73   private TreeMultimap<String, Integer> createPopulate() {
74     TreeMultimap<String, Integer> multimap =
75         TreeMultimap.create(StringLength.COMPARATOR, DECREASING_INT_COMPARATOR);
76     multimap.put("google", 2);
77     multimap.put("google", 6);
78     multimap.put(null, 3);
79     multimap.put(null, 1);
80     multimap.put(null, 7);
81     multimap.put("tree", 0);
82     multimap.put("tree", null);
83     return multimap;
84   }
85 
86   /** Test that a TreeMultimap created from another uses the natural ordering. */
testMultimapCreateFromTreeMultimap()87   public void testMultimapCreateFromTreeMultimap() {
88     TreeMultimap<String, Integer> tree =
89         TreeMultimap.create(StringLength.COMPARATOR, DECREASING_INT_COMPARATOR);
90     tree.put("google", 2);
91     tree.put("google", 6);
92     tree.put("tree", 0);
93     tree.put("tree", 3);
94     assertThat(tree.keySet()).containsExactly("tree", "google").inOrder();
95     assertThat(tree.get("google")).containsExactly(6, 2).inOrder();
96 
97     TreeMultimap<String, Integer> copy = TreeMultimap.create(tree);
98     assertEquals(tree, copy);
99     assertThat(copy.keySet()).containsExactly("google", "tree").inOrder();
100     assertThat(copy.get("google")).containsExactly(2, 6).inOrder();
101     assertEquals(Ordering.natural(), copy.keyComparator());
102     assertEquals(Ordering.natural(), copy.valueComparator());
103     assertEquals(Ordering.natural(), copy.get("google").comparator());
104   }
105 
testToString()106   public void testToString() {
107     Multimap<String, Integer> multimap = create();
108     multimap.put("foo", 3);
109     multimap.put("bar", 1);
110     multimap.putAll("foo", Arrays.asList(-1, 2, 4));
111     multimap.putAll("bar", Arrays.asList(2, 3));
112     multimap.put("foo", 1);
113     assertEquals("{bar=[3, 2, 1], foo=[4, 3, 2, 1, -1]}", multimap.toString());
114   }
115 
testGetComparator()116   public void testGetComparator() {
117     TreeMultimap<String, Integer> multimap = createPopulate();
118     assertEquals(StringLength.COMPARATOR, multimap.keyComparator());
119     assertEquals(DECREASING_INT_COMPARATOR, multimap.valueComparator());
120   }
121 
testOrderedGet()122   public void testOrderedGet() {
123     TreeMultimap<String, Integer> multimap = createPopulate();
124     assertThat(multimap.get(null)).containsExactly(7, 3, 1).inOrder();
125     assertThat(multimap.get("google")).containsExactly(6, 2).inOrder();
126     assertThat(multimap.get("tree")).containsExactly(null, 0).inOrder();
127   }
128 
testOrderedKeySet()129   public void testOrderedKeySet() {
130     TreeMultimap<String, Integer> multimap = createPopulate();
131     assertThat(multimap.keySet()).containsExactly(null, "tree", "google").inOrder();
132   }
133 
testOrderedAsMapEntries()134   public void testOrderedAsMapEntries() {
135     TreeMultimap<String, Integer> multimap = createPopulate();
136     Iterator<Entry<String, Collection<Integer>>> iterator = multimap.asMap().entrySet().iterator();
137     Entry<String, Collection<Integer>> entry = iterator.next();
138     assertEquals(null, entry.getKey());
139     assertThat(entry.getValue()).containsExactly(7, 3, 1);
140     entry = iterator.next();
141     assertEquals("tree", entry.getKey());
142     assertThat(entry.getValue()).containsExactly(null, 0);
143     entry = iterator.next();
144     assertEquals("google", entry.getKey());
145     assertThat(entry.getValue()).containsExactly(6, 2);
146   }
147 
testOrderedEntries()148   public void testOrderedEntries() {
149     TreeMultimap<String, Integer> multimap = createPopulate();
150     assertThat(multimap.entries())
151         .containsExactly(
152             Maps.immutableEntry((String) null, 7),
153             Maps.immutableEntry((String) null, 3),
154             Maps.immutableEntry((String) null, 1),
155             Maps.immutableEntry("tree", (Integer) null),
156             Maps.immutableEntry("tree", 0),
157             Maps.immutableEntry("google", 6),
158             Maps.immutableEntry("google", 2))
159         .inOrder();
160   }
161 
testOrderedValues()162   public void testOrderedValues() {
163     TreeMultimap<String, Integer> multimap = createPopulate();
164     assertThat(multimap.values()).containsExactly(7, 3, 1, null, 0, 6, 2).inOrder();
165   }
166 
testComparator()167   public void testComparator() {
168     TreeMultimap<String, Integer> multimap = createPopulate();
169     assertEquals(DECREASING_INT_COMPARATOR, multimap.get("foo").comparator());
170     assertEquals(DECREASING_INT_COMPARATOR, multimap.get("missing").comparator());
171   }
172 
testMultimapComparators()173   public void testMultimapComparators() {
174     Multimap<String, Integer> multimap = create();
175     multimap.put("foo", 3);
176     multimap.put("bar", 1);
177     multimap.putAll("foo", Arrays.asList(-1, 2, 4));
178     multimap.putAll("bar", Arrays.asList(2, 3));
179     multimap.put("foo", 1);
180     TreeMultimap<String, Integer> copy =
181         TreeMultimap.create(StringLength.COMPARATOR, DECREASING_INT_COMPARATOR);
182     copy.putAll(multimap);
183     assertEquals(multimap, copy);
184     assertEquals(StringLength.COMPARATOR, copy.keyComparator());
185     assertEquals(DECREASING_INT_COMPARATOR, copy.valueComparator());
186   }
187 
testSortedKeySet()188   public void testSortedKeySet() {
189     TreeMultimap<String, Integer> multimap = createPopulate();
190     SortedSet<String> keySet = multimap.keySet();
191 
192     assertEquals(null, keySet.first());
193     assertEquals("google", keySet.last());
194     assertEquals(StringLength.COMPARATOR, keySet.comparator());
195     assertEquals(Sets.newHashSet(null, "tree"), keySet.headSet("yahoo"));
196     assertEquals(Sets.newHashSet("google"), keySet.tailSet("yahoo"));
197     assertEquals(Sets.newHashSet("tree"), keySet.subSet("ask", "yahoo"));
198   }
199 
200   @GwtIncompatible // SerializableTester
testExplicitComparatorSerialization()201   public void testExplicitComparatorSerialization() {
202     TreeMultimap<String, Integer> multimap = createPopulate();
203     TreeMultimap<String, Integer> copy = SerializableTester.reserializeAndAssert(multimap);
204     assertThat(copy.values()).containsExactly(7, 3, 1, null, 0, 6, 2).inOrder();
205     assertThat(copy.keySet()).containsExactly(null, "tree", "google").inOrder();
206     assertEquals(multimap.keyComparator(), copy.keyComparator());
207     assertEquals(multimap.valueComparator(), copy.valueComparator());
208   }
209 }
210