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