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