1 /* 2 * Copyright (C) 2010 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.base.Function; 24 import com.google.common.base.Predicate; 25 import com.google.common.collect.Maps.EntryTransformer; 26 import com.google.common.collect.testing.SortedMapInterfaceTest; 27 import com.google.common.testing.NullPointerTester; 28 29 import junit.framework.TestCase; 30 31 import java.util.Comparator; 32 import java.util.Map; 33 import java.util.Map.Entry; 34 import java.util.SortedMap; 35 36 /** 37 * Tests for SortedMaps. 38 * 39 * @author Louis Wasserman 40 */ 41 @GwtCompatible(emulated = true) 42 @SuppressWarnings("deprecation") 43 public class SortedMapsTest extends TestCase { 44 45 private static final EntryTransformer<Object, Object, Object> ALWAYS_NULL = 46 new EntryTransformer<Object, Object, Object>() { 47 @Override 48 public Object transformEntry(Object k, Object v1) { 49 return null; 50 } 51 }; 52 53 @GwtIncompatible("NullPointerTester") 54 public void testNullPointer() throws Exception { 55 NullPointerTester nullPointerTester = new NullPointerTester(); 56 nullPointerTester.setDefault(EntryTransformer.class, ALWAYS_NULL); 57 nullPointerTester.setDefault( 58 SortedMap.class, Maps.<String, String>newTreeMap()); 59 nullPointerTester.testAllPublicStaticMethods(SortedMaps.class); 60 } 61 62 public void testTransformSortedValues() { 63 SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9); 64 Function<Integer, Double> sqrt = new Function<Integer, Double>() { 65 @Override 66 public Double apply(Integer in) { 67 return Math.sqrt(in); 68 } 69 }; 70 SortedMap<String, Double> transformed = 71 SortedMaps.transformValues(map, sqrt); 72 73 assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed); 74 } 75 76 public void testTransformSortedEntries() { 77 SortedMap<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9"); 78 EntryTransformer<String, String, String> concat = 79 new EntryTransformer<String, String, String>() { 80 @Override 81 public String transformEntry(String key, String value) { 82 return key + value; 83 } 84 }; 85 SortedMap<String, String> transformed = 86 SortedMaps.transformEntries(map, concat); 87 88 assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed); 89 } 90 91 // Not testing Map methods of SortedMaps.filter*, since the implementation 92 // doesn't override Maps.FilteredEntryMap, which is already tested. 93 94 private static final Predicate<Integer> EVEN = 95 new Predicate<Integer>() { 96 @Override 97 public boolean apply(Integer input) { 98 return input % 2 == 0; 99 } 100 }; 101 102 public void testFilterKeys() { 103 Comparator<Integer> comparator = Ordering.natural(); 104 SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator); 105 unfiltered.put(1, "one"); 106 unfiltered.put(2, "two"); 107 unfiltered.put(3, "three"); 108 unfiltered.put(4, "four"); 109 unfiltered.put(5, "five"); 110 unfiltered.put(6, "six"); 111 unfiltered.put(7, "seven"); 112 SortedMap<Integer, String> filtered 113 = SortedMaps.filterKeys(unfiltered, EVEN); 114 ASSERT.that(filtered.keySet()).hasContentsInOrder(2, 4, 6); 115 assertSame(comparator, filtered.comparator()); 116 assertEquals((Integer) 2, filtered.firstKey()); 117 assertEquals((Integer) 6, filtered.lastKey()); 118 ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(2, 4); 119 ASSERT.that(filtered.tailMap(3).keySet()).hasContentsInOrder(4, 6); 120 ASSERT.that(filtered.subMap(3, 5).keySet()).hasContentsInOrder(4); 121 } 122 123 private static final Predicate<String> NOT_LENGTH_3 = 124 new Predicate<String>() { 125 @Override 126 public boolean apply(String input) { 127 return input == null || input.length() != 3; 128 } 129 }; 130 131 public void testFilterValues() { 132 Comparator<Integer> comparator = Ordering.natural(); 133 SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator); 134 unfiltered.put(1, "one"); 135 unfiltered.put(2, "two"); 136 unfiltered.put(3, "three"); 137 unfiltered.put(4, "four"); 138 unfiltered.put(5, "five"); 139 unfiltered.put(6, "six"); 140 unfiltered.put(7, "seven"); 141 SortedMap<Integer, String> filtered 142 = SortedMaps.filterValues(unfiltered, NOT_LENGTH_3); 143 ASSERT.that(filtered.keySet()).hasContentsInOrder(3, 4, 5, 7); 144 assertSame(comparator, filtered.comparator()); 145 assertEquals((Integer) 3, filtered.firstKey()); 146 assertEquals((Integer) 7, filtered.lastKey()); 147 ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(3, 4); 148 ASSERT.that(filtered.tailMap(4).keySet()).hasContentsInOrder(4, 5, 7); 149 ASSERT.that(filtered.subMap(4, 6).keySet()).hasContentsInOrder(4, 5); 150 } 151 152 private static final Predicate<Map.Entry<Integer, String>> 153 EVEN_AND_LENGTH_3 = new Predicate<Map.Entry<Integer, String>>() { 154 @Override public boolean apply(Entry<Integer, String> entry) { 155 return (entry.getKey() == null || entry.getKey() % 2 == 0) 156 && (entry.getValue() == null || entry.getValue().length() == 3); 157 } 158 }; 159 160 private static class ContainsKeySafeSortedMap 161 extends ForwardingSortedMap<Integer, String> { 162 SortedMap<Integer, String> delegate 163 = Maps.newTreeMap(Ordering.natural().nullsFirst()); 164 165 @Override protected SortedMap<Integer, String> delegate() { 166 return delegate; 167 } 168 169 // Needed by MapInterfaceTest.testContainsKey() 170 @Override public boolean containsKey(Object key) { 171 try { 172 return super.containsKey(key); 173 } catch (ClassCastException e) { 174 return false; 175 } 176 } 177 } 178 179 public static class FilteredEntriesSortedMapInterfaceTest 180 extends SortedMapInterfaceTest<Integer, String> { 181 public FilteredEntriesSortedMapInterfaceTest() { 182 super(true, true, true, true, true); 183 } 184 185 @Override protected SortedMap<Integer, String> makeEmptyMap() { 186 SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap(); 187 unfiltered.put(1, "one"); 188 unfiltered.put(3, "three"); 189 unfiltered.put(4, "four"); 190 unfiltered.put(5, "five"); 191 return SortedMaps.filterEntries(unfiltered, EVEN_AND_LENGTH_3); 192 } 193 194 @Override protected SortedMap<Integer, String> makePopulatedMap() { 195 SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap(); 196 unfiltered.put(1, "one"); 197 unfiltered.put(2, "two"); 198 unfiltered.put(3, "three"); 199 unfiltered.put(4, "four"); 200 unfiltered.put(5, "five"); 201 unfiltered.put(6, "six"); 202 return SortedMaps.filterEntries(unfiltered, EVEN_AND_LENGTH_3); 203 } 204 205 @Override protected Integer getKeyNotInPopulatedMap() { 206 return 10; 207 } 208 209 @Override protected String getValueNotInPopulatedMap() { 210 return "ten"; 211 } 212 213 // Iterators don't support remove. 214 @Override public void testEntrySetIteratorRemove() {} 215 @Override public void testValuesIteratorRemove() {} 216 217 // These tests fail on GWT. 218 // TODO: Investigate why. 219 @Override public void testEntrySetRemoveAll() {} 220 @Override public void testEntrySetRetainAll() {} 221 } 222 } 223