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