1 /* 2 * Copyright (C) 2008 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.primitives; 18 19 import static java.lang.Double.NaN; 20 import static org.junit.contrib.truth.Truth.ASSERT; 21 22 import com.google.common.annotations.GwtCompatible; 23 import com.google.common.annotations.GwtIncompatible; 24 import com.google.common.collect.testing.Helpers; 25 import com.google.common.testing.NullPointerTester; 26 import com.google.common.testing.SerializableTester; 27 28 import junit.framework.TestCase; 29 30 import java.util.Arrays; 31 import java.util.Collection; 32 import java.util.Collections; 33 import java.util.Comparator; 34 import java.util.List; 35 36 /** 37 * Unit test for {@link Doubles}. 38 * 39 * @author Kevin Bourrillion 40 */ 41 @GwtCompatible(emulated = true) 42 @SuppressWarnings("cast") // redundant casts are intentional and harmless 43 public class DoublesTest extends TestCase { 44 private static final double[] EMPTY = {}; 45 private static final double[] ARRAY1 = {(double) 1}; 46 private static final double[] ARRAY234 47 = {(double) 2, (double) 3, (double) 4}; 48 49 private static final double LEAST = Double.NEGATIVE_INFINITY; 50 private static final double GREATEST = Double.POSITIVE_INFINITY; 51 52 private static final double[] NUMBERS = new double[] { 53 LEAST, -Double.MAX_VALUE, -1.0, -0.0, 0.0, 1.0, Double.MAX_VALUE, GREATEST, 54 Double.MIN_NORMAL, -Double.MIN_NORMAL, Double.MIN_VALUE, -Double.MIN_VALUE, 55 Integer.MIN_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE 56 }; 57 58 private static final double[] VALUES 59 = Doubles.concat(NUMBERS, new double[] {NaN}); 60 61 public void testHashCode() { 62 for (double value : VALUES) { 63 assertEquals(((Double) value).hashCode(), Doubles.hashCode(value)); 64 } 65 } 66 67 public void testIsFinite() { 68 for (double value : NUMBERS) { 69 assertEquals(!(Double.isNaN(value) || Double.isInfinite(value)), Doubles.isFinite(value)); 70 } 71 } 72 73 public void testCompare() { 74 for (double x : VALUES) { 75 for (double y : VALUES) { 76 // note: spec requires only that the sign is the same 77 assertEquals(x + ", " + y, 78 Double.valueOf(x).compareTo(y), 79 Doubles.compare(x, y)); 80 } 81 } 82 } 83 84 public void testContains() { 85 assertFalse(Doubles.contains(EMPTY, (double) 1)); 86 assertFalse(Doubles.contains(ARRAY1, (double) 2)); 87 assertFalse(Doubles.contains(ARRAY234, (double) 1)); 88 assertTrue(Doubles.contains(new double[] {(double) -1}, (double) -1)); 89 assertTrue(Doubles.contains(ARRAY234, (double) 2)); 90 assertTrue(Doubles.contains(ARRAY234, (double) 3)); 91 assertTrue(Doubles.contains(ARRAY234, (double) 4)); 92 93 for (double value : NUMBERS) { 94 assertTrue("" + value, 95 Doubles.contains(new double[] {5.0, value}, value)); 96 } 97 assertFalse(Doubles.contains(new double[] {5.0, NaN}, NaN)); 98 } 99 100 public void testIndexOf() { 101 assertEquals(-1, Doubles.indexOf(EMPTY, (double) 1)); 102 assertEquals(-1, Doubles.indexOf(ARRAY1, (double) 2)); 103 assertEquals(-1, Doubles.indexOf(ARRAY234, (double) 1)); 104 assertEquals(0, Doubles.indexOf( 105 new double[] {(double) -1}, (double) -1)); 106 assertEquals(0, Doubles.indexOf(ARRAY234, (double) 2)); 107 assertEquals(1, Doubles.indexOf(ARRAY234, (double) 3)); 108 assertEquals(2, Doubles.indexOf(ARRAY234, (double) 4)); 109 assertEquals(1, Doubles.indexOf( 110 new double[] { (double) 2, (double) 3, (double) 2, (double) 3 }, 111 (double) 3)); 112 113 for (double value : NUMBERS) { 114 assertEquals("" + value, 115 1, Doubles.indexOf(new double[] {5.0, value}, value)); 116 } 117 assertEquals(-1, Doubles.indexOf(new double[] {5.0, NaN}, NaN)); 118 } 119 120 public void testIndexOf_arrayTarget() { 121 assertEquals(0, Doubles.indexOf(EMPTY, EMPTY)); 122 assertEquals(0, Doubles.indexOf(ARRAY234, EMPTY)); 123 assertEquals(-1, Doubles.indexOf(EMPTY, ARRAY234)); 124 assertEquals(-1, Doubles.indexOf(ARRAY234, ARRAY1)); 125 assertEquals(-1, Doubles.indexOf(ARRAY1, ARRAY234)); 126 assertEquals(0, Doubles.indexOf(ARRAY1, ARRAY1)); 127 assertEquals(0, Doubles.indexOf(ARRAY234, ARRAY234)); 128 assertEquals(0, Doubles.indexOf( 129 ARRAY234, new double[] { (double) 2, (double) 3 })); 130 assertEquals(1, Doubles.indexOf( 131 ARRAY234, new double[] { (double) 3, (double) 4 })); 132 assertEquals(1, Doubles.indexOf(ARRAY234, new double[] { (double) 3 })); 133 assertEquals(2, Doubles.indexOf(ARRAY234, new double[] { (double) 4 })); 134 assertEquals(1, Doubles.indexOf(new double[] { (double) 2, (double) 3, 135 (double) 3, (double) 3, (double) 3 }, 136 new double[] { (double) 3 } 137 )); 138 assertEquals(2, Doubles.indexOf( 139 new double[] { (double) 2, (double) 3, (double) 2, 140 (double) 3, (double) 4, (double) 2, (double) 3}, 141 new double[] { (double) 2, (double) 3, (double) 4} 142 )); 143 assertEquals(1, Doubles.indexOf( 144 new double[] { (double) 2, (double) 2, (double) 3, 145 (double) 4, (double) 2, (double) 3, (double) 4}, 146 new double[] { (double) 2, (double) 3, (double) 4} 147 )); 148 assertEquals(-1, Doubles.indexOf( 149 new double[] { (double) 4, (double) 3, (double) 2}, 150 new double[] { (double) 2, (double) 3, (double) 4} 151 )); 152 153 for (double value : NUMBERS) { 154 assertEquals("" + value, 1, Doubles.indexOf( 155 new double[] {5.0, value, value, 5.0}, new double[] {value, value})); 156 } 157 assertEquals(-1, Doubles.indexOf( 158 new double[] {5.0, NaN, NaN, 5.0}, new double[] {NaN, NaN})); 159 } 160 161 public void testLastIndexOf() { 162 assertEquals(-1, Doubles.lastIndexOf(EMPTY, (double) 1)); 163 assertEquals(-1, Doubles.lastIndexOf(ARRAY1, (double) 2)); 164 assertEquals(-1, Doubles.lastIndexOf(ARRAY234, (double) 1)); 165 assertEquals(0, Doubles.lastIndexOf( 166 new double[] {(double) -1}, (double) -1)); 167 assertEquals(0, Doubles.lastIndexOf(ARRAY234, (double) 2)); 168 assertEquals(1, Doubles.lastIndexOf(ARRAY234, (double) 3)); 169 assertEquals(2, Doubles.lastIndexOf(ARRAY234, (double) 4)); 170 assertEquals(3, Doubles.lastIndexOf( 171 new double[] { (double) 2, (double) 3, (double) 2, (double) 3 }, 172 (double) 3)); 173 174 for (double value : NUMBERS) { 175 assertEquals("" + value, 176 0, Doubles.lastIndexOf(new double[] {value, 5.0}, value)); 177 } 178 assertEquals(-1, Doubles.lastIndexOf(new double[] {NaN, 5.0}, NaN)); 179 } 180 181 public void testMax_noArgs() { 182 try { 183 Doubles.max(); 184 fail(); 185 } catch (IllegalArgumentException expected) { 186 } 187 } 188 189 public void testMax() { 190 assertEquals(LEAST, Doubles.max(LEAST)); 191 assertEquals(GREATEST, Doubles.max(GREATEST)); 192 assertEquals((double) 9, Doubles.max( 193 (double) 8, (double) 6, (double) 7, 194 (double) 5, (double) 3, (double) 0, (double) 9)); 195 196 assertEquals(0.0, Doubles.max(-0.0, 0.0)); 197 assertEquals(0.0, Doubles.max(0.0, -0.0)); 198 assertEquals(GREATEST, Doubles.max(NUMBERS)); 199 assertTrue(Double.isNaN(Doubles.max(VALUES))); 200 } 201 202 public void testMin_noArgs() { 203 try { 204 Doubles.min(); 205 fail(); 206 } catch (IllegalArgumentException expected) { 207 } 208 } 209 210 public void testMin() { 211 assertEquals(LEAST, Doubles.min(LEAST)); 212 assertEquals(GREATEST, Doubles.min(GREATEST)); 213 assertEquals((double) 0, Doubles.min( 214 (double) 8, (double) 6, (double) 7, 215 (double) 5, (double) 3, (double) 0, (double) 9)); 216 217 assertEquals(-0.0, Doubles.min(-0.0, 0.0)); 218 assertEquals(-0.0, Doubles.min(0.0, -0.0)); 219 assertEquals(LEAST, Doubles.min(NUMBERS)); 220 assertTrue(Double.isNaN(Doubles.min(VALUES))); 221 } 222 223 public void testConcat() { 224 assertTrue(Arrays.equals(EMPTY, Doubles.concat())); 225 assertTrue(Arrays.equals(EMPTY, Doubles.concat(EMPTY))); 226 assertTrue(Arrays.equals(EMPTY, Doubles.concat(EMPTY, EMPTY, EMPTY))); 227 assertTrue(Arrays.equals(ARRAY1, Doubles.concat(ARRAY1))); 228 assertNotSame(ARRAY1, Doubles.concat(ARRAY1)); 229 assertTrue(Arrays.equals(ARRAY1, Doubles.concat(EMPTY, ARRAY1, EMPTY))); 230 assertTrue(Arrays.equals( 231 new double[] {(double) 1, (double) 1, (double) 1}, 232 Doubles.concat(ARRAY1, ARRAY1, ARRAY1))); 233 assertTrue(Arrays.equals( 234 new double[] {(double) 1, (double) 2, (double) 3, (double) 4}, 235 Doubles.concat(ARRAY1, ARRAY234))); 236 } 237 238 public void testEnsureCapacity() { 239 assertSame(EMPTY, Doubles.ensureCapacity(EMPTY, 0, 1)); 240 assertSame(ARRAY1, Doubles.ensureCapacity(ARRAY1, 0, 1)); 241 assertSame(ARRAY1, Doubles.ensureCapacity(ARRAY1, 1, 1)); 242 assertTrue(Arrays.equals( 243 new double[] {(double) 1, (double) 0, (double) 0}, 244 Doubles.ensureCapacity(ARRAY1, 2, 1))); 245 } 246 247 public void testEnsureCapacity_fail() { 248 try { 249 Doubles.ensureCapacity(ARRAY1, -1, 1); 250 fail(); 251 } catch (IllegalArgumentException expected) { 252 } 253 try { 254 // notice that this should even fail when no growth was needed 255 Doubles.ensureCapacity(ARRAY1, 1, -1); 256 fail(); 257 } catch (IllegalArgumentException expected) { 258 } 259 } 260 261 @GwtIncompatible("Double.toString returns different value in GWT.") 262 public void testJoin() { 263 assertEquals("", Doubles.join(",", EMPTY)); 264 assertEquals("1.0", Doubles.join(",", ARRAY1)); 265 assertEquals("1.0,2.0", Doubles.join(",", (double) 1, (double) 2)); 266 assertEquals("1.02.03.0", 267 Doubles.join("", (double) 1, (double) 2, (double) 3)); 268 } 269 270 public void testJoinNonTrivialDoubles() { 271 assertEquals("", Doubles.join(",", EMPTY)); 272 assertEquals("1.2", Doubles.join(",", 1.2)); 273 assertEquals("1.3,2.4", Doubles.join(",", 1.3, 2.4)); 274 assertEquals("1.42.53.6", Doubles.join("", 1.4, 2.5, 3.6)); 275 } 276 277 public void testLexicographicalComparator() { 278 List<double[]> ordered = Arrays.asList( 279 new double[] {}, 280 new double[] {LEAST}, 281 new double[] {LEAST, LEAST}, 282 new double[] {LEAST, (double) 1}, 283 new double[] {(double) 1}, 284 new double[] {(double) 1, LEAST}, 285 new double[] {GREATEST, Double.MAX_VALUE}, 286 new double[] {GREATEST, GREATEST}, 287 new double[] {GREATEST, GREATEST, GREATEST}); 288 289 Comparator<double[]> comparator = Doubles.lexicographicalComparator(); 290 Helpers.testComparator(comparator, ordered); 291 } 292 293 @GwtIncompatible("SerializableTester") 294 public void testLexicographicalComparatorSerializable() { 295 Comparator<double[]> comparator = Doubles.lexicographicalComparator(); 296 assertSame(comparator, SerializableTester.reserialize(comparator)); 297 } 298 299 public void testToArray() { 300 // need explicit type parameter to avoid javac warning!? 301 List<Double> none = Arrays.<Double>asList(); 302 assertTrue(Arrays.equals(EMPTY, Doubles.toArray(none))); 303 304 List<Double> one = Arrays.asList((double) 1); 305 assertTrue(Arrays.equals(ARRAY1, Doubles.toArray(one))); 306 307 double[] array = {(double) 0, (double) 1, Math.PI}; 308 309 List<Double> three = Arrays.asList((double) 0, (double) 1, Math.PI); 310 assertTrue(Arrays.equals(array, Doubles.toArray(three))); 311 312 assertTrue(Arrays.equals(array, Doubles.toArray(Doubles.asList(array)))); 313 } 314 315 public void testToArray_threadSafe() { 316 for (int delta : new int[] { +1, 0, -1 }) { 317 for (int i = 0; i < VALUES.length; i++) { 318 List<Double> list = Doubles.asList(VALUES).subList(0, i); 319 Collection<Double> misleadingSize = 320 Helpers.misleadingSizeCollection(delta); 321 misleadingSize.addAll(list); 322 double[] arr = Doubles.toArray(misleadingSize); 323 assertEquals(i, arr.length); 324 for (int j = 0; j < i; j++) { 325 assertEquals(VALUES[j], arr[j]); 326 } 327 } 328 } 329 } 330 331 public void testToArray_withNull() { 332 List<Double> list = Arrays.asList((double) 0, (double) 1, null); 333 try { 334 Doubles.toArray(list); 335 fail(); 336 } catch (NullPointerException expected) { 337 } 338 } 339 340 public void testAsList_isAView() { 341 double[] array = {(double) 0, (double) 1}; 342 List<Double> list = Doubles.asList(array); 343 list.set(0, (double) 2); 344 assertTrue(Arrays.equals(new double[] {(double) 2, (double) 1}, array)); 345 array[1] = (double) 3; 346 ASSERT.that(list).hasContentsInOrder((double) 2, (double) 3); 347 } 348 349 public void testAsList_toArray_roundTrip() { 350 double[] array = { (double) 0, (double) 1, (double) 2 }; 351 List<Double> list = Doubles.asList(array); 352 double[] newArray = Doubles.toArray(list); 353 354 // Make sure it returned a copy 355 list.set(0, (double) 4); 356 assertTrue(Arrays.equals( 357 new double[] { (double) 0, (double) 1, (double) 2 }, newArray)); 358 newArray[1] = (double) 5; 359 assertEquals((double) 1, (double) list.get(1)); 360 } 361 362 // This test stems from a real bug found by andrewk 363 public void testAsList_subList_toArray_roundTrip() { 364 double[] array = { (double) 0, (double) 1, (double) 2, (double) 3 }; 365 List<Double> list = Doubles.asList(array); 366 assertTrue(Arrays.equals(new double[] { (double) 1, (double) 2 }, 367 Doubles.toArray(list.subList(1, 3)))); 368 assertTrue(Arrays.equals(new double[] {}, 369 Doubles.toArray(list.subList(2, 2)))); 370 } 371 372 public void testAsListEmpty() { 373 assertSame(Collections.emptyList(), Doubles.asList(EMPTY)); 374 } 375 376 @GwtIncompatible("NullPointerTester") 377 public void testNulls() throws Exception { 378 NullPointerTester tester = new NullPointerTester(); 379 tester.setDefault(double[].class, new double[0]); 380 tester.testAllPublicStaticMethods(Doubles.class); 381 } 382 } 383