1 /* 2 * Copyright (C) 2012 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15 package com.google.common.collect; 16 17 import static com.google.common.collect.BoundType.OPEN; 18 19 import com.google.common.annotations.GwtIncompatible; 20 import com.google.common.testing.CollectorTester; 21 import com.google.common.testing.SerializableTester; 22 import java.util.Map.Entry; 23 import java.util.NoSuchElementException; 24 import junit.framework.TestCase; 25 26 /** 27 * Tests for {@code ImmutableRangeMap}. 28 * 29 * @author Louis Wasserman 30 */ 31 @GwtIncompatible // NavigableMap 32 public class ImmutableRangeMapTest extends TestCase { 33 private static final ImmutableList<Range<Integer>> RANGES; 34 private static final int MIN_BOUND = 0; 35 private static final int MAX_BOUND = 10; 36 37 static { 38 ImmutableList.Builder<Range<Integer>> builder = ImmutableList.builder(); 39 all()40 builder.add(Range.<Integer>all()); 41 42 // Add one-ended ranges 43 for (int i = MIN_BOUND; i <= MAX_BOUND; i++) { 44 for (BoundType type : BoundType.values()) { Range.upTo(i, type)45 builder.add(Range.upTo(i, type)); Range.downTo(i, type)46 builder.add(Range.downTo(i, type)); 47 } 48 } 49 50 // Add two-ended ranges 51 for (int i = MIN_BOUND; i <= MAX_BOUND; i++) { 52 for (int j = i + 1; j <= MAX_BOUND; j++) { 53 for (BoundType lowerType : BoundType.values()) { 54 for (BoundType upperType : BoundType.values()) { 55 if (i == j & lowerType == OPEN & upperType == OPEN) { 56 continue; 57 } Range.range(i, lowerType, j, upperType)58 builder.add(Range.range(i, lowerType, j, upperType)); 59 } 60 } 61 } 62 } 63 RANGES = builder.build(); 64 } 65 testBuilderRejectsEmptyRanges()66 public void testBuilderRejectsEmptyRanges() { 67 for (int i = MIN_BOUND; i <= MAX_BOUND; i++) { 68 ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder(); 69 try { 70 builder.put(Range.closedOpen(i, i), 1); 71 fail("Expected IllegalArgumentException"); 72 } catch (IllegalArgumentException expected) { 73 // success 74 } 75 try { 76 builder.put(Range.openClosed(i, i), 1); 77 fail("Expected IllegalArgumentException"); 78 } catch (IllegalArgumentException expected) { 79 } 80 } 81 } 82 testOverlapRejection()83 public void testOverlapRejection() { 84 for (Range<Integer> range1 : RANGES) { 85 for (Range<Integer> range2 : RANGES) { 86 boolean expectRejection = 87 range1.isConnected(range2) && !range1.intersection(range2).isEmpty(); 88 ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder(); 89 builder.put(range1, 1).put(range2, 2); 90 try { 91 ImmutableRangeMap<Integer, Integer> unused = builder.build(); 92 assertFalse(expectRejection); 93 } catch (IllegalArgumentException e) { 94 assertTrue(expectRejection); 95 } 96 } 97 } 98 } 99 testGet()100 public void testGet() { 101 for (Range<Integer> range1 : RANGES) { 102 for (Range<Integer> range2 : RANGES) { 103 if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { 104 ImmutableRangeMap<Integer, Integer> rangeMap = 105 ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); 106 107 for (int i = MIN_BOUND; i <= MAX_BOUND; i++) { 108 Integer expectedValue = null; 109 if (range1.contains(i)) { 110 expectedValue = 1; 111 } else if (range2.contains(i)) { 112 expectedValue = 2; 113 } 114 115 assertEquals(expectedValue, rangeMap.get(i)); 116 } 117 } 118 } 119 } 120 } 121 testSpanEmpty()122 public void testSpanEmpty() { 123 try { 124 ImmutableRangeMap.of().span(); 125 fail("Expected NoSuchElementException"); 126 } catch (NoSuchElementException expected) { 127 } 128 } 129 testSpanSingleRange()130 public void testSpanSingleRange() { 131 for (Range<Integer> range : RANGES) { 132 RangeMap<Integer, Integer> rangemap = 133 ImmutableRangeMap.<Integer, Integer>builder().put(range, 1).build(); 134 assertEquals(range, rangemap.span()); 135 } 136 } 137 testSpanTwoRanges()138 public void testSpanTwoRanges() { 139 for (Range<Integer> range1 : RANGES) { 140 for (Range<Integer> range2 : RANGES) { 141 if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { 142 RangeMap<Integer, Integer> rangemap = 143 ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); 144 assertEquals(range1.span(range2), rangemap.span()); 145 } 146 } 147 } 148 } 149 testGetEntry()150 public void testGetEntry() { 151 for (Range<Integer> range1 : RANGES) { 152 for (Range<Integer> range2 : RANGES) { 153 if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { 154 ImmutableRangeMap<Integer, Integer> rangeMap = 155 ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); 156 157 for (int i = MIN_BOUND; i <= MAX_BOUND; i++) { 158 Entry<Range<Integer>, Integer> expectedEntry = null; 159 if (range1.contains(i)) { 160 expectedEntry = Maps.immutableEntry(range1, 1); 161 } else if (range2.contains(i)) { 162 expectedEntry = Maps.immutableEntry(range2, 2); 163 } 164 165 assertEquals(expectedEntry, rangeMap.getEntry(i)); 166 } 167 } 168 } 169 } 170 } 171 testGetLargeRangeMap()172 public void testGetLargeRangeMap() { 173 ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder(); 174 for (int i = 0; i < 100; i++) { 175 builder.put(Range.closedOpen(i, i + 1), i); 176 } 177 ImmutableRangeMap<Integer, Integer> map = builder.build(); 178 for (int i = 0; i < 100; i++) { 179 assertEquals(Integer.valueOf(i), map.get(i)); 180 } 181 } 182 183 @AndroidIncompatible // slow testAsMapOfRanges()184 public void testAsMapOfRanges() { 185 for (Range<Integer> range1 : RANGES) { 186 for (Range<Integer> range2 : RANGES) { 187 if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { 188 ImmutableRangeMap<Integer, Integer> rangeMap = 189 ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); 190 191 ImmutableMap<Range<Integer>, Integer> expectedAsMap = 192 ImmutableMap.of(range1, 1, range2, 2); 193 ImmutableMap<Range<Integer>, Integer> asMap = rangeMap.asMapOfRanges(); 194 ImmutableMap<Range<Integer>, Integer> descendingMap = rangeMap.asDescendingMapOfRanges(); 195 assertEquals(expectedAsMap, asMap); 196 assertEquals(expectedAsMap, descendingMap); 197 SerializableTester.reserializeAndAssert(asMap); 198 SerializableTester.reserializeAndAssert(descendingMap); 199 assertEquals( 200 ImmutableList.copyOf(asMap.entrySet()).reverse(), 201 ImmutableList.copyOf(descendingMap.entrySet())); 202 203 for (Range<Integer> query : RANGES) { 204 assertEquals(expectedAsMap.get(query), asMap.get(query)); 205 } 206 } 207 } 208 } 209 } 210 testSubRangeMap()211 public void testSubRangeMap() { 212 for (Range<Integer> range1 : RANGES) { 213 for (Range<Integer> range2 : RANGES) { 214 if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { 215 for (Range<Integer> subRange : RANGES) { 216 ImmutableRangeMap<Integer, Integer> rangeMap = 217 ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); 218 219 ImmutableRangeMap.Builder<Integer, Integer> expectedBuilder = 220 ImmutableRangeMap.builder(); 221 for (Entry<Range<Integer>, Integer> entry : rangeMap.asMapOfRanges().entrySet()) { 222 if (entry.getKey().isConnected(subRange) 223 && !entry.getKey().intersection(subRange).isEmpty()) { 224 expectedBuilder.put(entry.getKey().intersection(subRange), entry.getValue()); 225 } 226 } 227 228 ImmutableRangeMap<Integer, Integer> expected = expectedBuilder.build(); 229 assertEquals(expected, rangeMap.subRangeMap(subRange)); 230 } 231 } 232 } 233 } 234 } 235 testSerialization()236 public void testSerialization() { 237 ImmutableRangeMap<Integer, Integer> emptyRangeMap = ImmutableRangeMap.of(); 238 SerializableTester.reserializeAndAssert(emptyRangeMap); 239 240 ImmutableRangeMap<Integer, Integer> nonEmptyRangeMap = 241 new ImmutableRangeMap.Builder<Integer, Integer>() 242 .put(Range.closed(2, 4), 5) 243 .put(Range.open(6, 7), 3) 244 .put(Range.closedOpen(8, 10), 4) 245 .put(Range.openClosed(15, 17), 2) 246 .build(); 247 248 ImmutableMap<Range<Integer>, Integer> test = nonEmptyRangeMap.asMapOfRanges(); 249 250 for (Range<Integer> range : test.keySet()) { 251 SerializableTester.reserializeAndAssert(range); 252 } 253 254 SerializableTester.reserializeAndAssert(test.keySet()); 255 256 SerializableTester.reserializeAndAssert(nonEmptyRangeMap); 257 } 258 testToImmutableRangeSet()259 public void testToImmutableRangeSet() { 260 Range<Integer> rangeOne = Range.closedOpen(1, 5); 261 Range<Integer> rangeTwo = Range.openClosed(6, 7); 262 ImmutableRangeMap<Integer, Integer> rangeMap = 263 new ImmutableRangeMap.Builder<Integer, Integer>().put(rangeOne, 1).put(rangeTwo, 6).build(); 264 CollectorTester.of( 265 ImmutableRangeMap.<Range<Integer>, Integer, Integer>toImmutableRangeMap( 266 k -> k, k -> k.lowerEndpoint())) 267 .expectCollects(rangeMap, rangeOne, rangeTwo); 268 } 269 } 270