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 com.google.common.truth.Truth.assertThat; 20 import static com.google.common.truth.Truth.assertWithMessage; 21 import static java.lang.Float.NaN; 22 23 import com.google.common.annotations.GwtCompatible; 24 import com.google.common.annotations.GwtIncompatible; 25 import com.google.common.annotations.J2ktIncompatible; 26 import com.google.common.base.Converter; 27 import com.google.common.collect.ImmutableList; 28 import com.google.common.collect.testing.Helpers; 29 import com.google.common.testing.NullPointerTester; 30 import com.google.common.testing.SerializableTester; 31 import java.util.Arrays; 32 import java.util.Collection; 33 import java.util.Collections; 34 import java.util.Comparator; 35 import java.util.List; 36 import junit.framework.TestCase; 37 import org.checkerframework.checker.nullness.qual.Nullable; 38 39 /** 40 * Unit test for {@link Floats}. 41 * 42 * @author Kevin Bourrillion 43 */ 44 @ElementTypesAreNonnullByDefault 45 @GwtCompatible(emulated = true) 46 public class FloatsTest extends TestCase { 47 private static final float[] EMPTY = {}; 48 private static final float[] ARRAY1 = {(float) 1}; 49 private static final float[] ARRAY234 = {(float) 2, (float) 3, (float) 4}; 50 51 private static final float LEAST = Float.NEGATIVE_INFINITY; 52 private static final float GREATEST = Float.POSITIVE_INFINITY; 53 54 private static final float[] NUMBERS = 55 new float[] { 56 LEAST, 57 -Float.MAX_VALUE, 58 -1f, 59 -0f, 60 0f, 61 1f, 62 Float.MAX_VALUE, 63 GREATEST, 64 Float.MIN_NORMAL, 65 -Float.MIN_NORMAL, 66 Float.MIN_VALUE, 67 -Float.MIN_VALUE, 68 Integer.MIN_VALUE, 69 Integer.MAX_VALUE, 70 Long.MIN_VALUE, 71 Long.MAX_VALUE 72 }; 73 74 private static final float[] VALUES = Floats.concat(NUMBERS, new float[] {NaN}); 75 testHashCode()76 public void testHashCode() { 77 for (float value : VALUES) { 78 assertThat(Floats.hashCode(value)).isEqualTo(((Float) value).hashCode()); 79 } 80 } 81 testIsFinite()82 public void testIsFinite() { 83 for (float value : NUMBERS) { 84 assertThat(Floats.isFinite(value)) 85 .isEqualTo(!(Float.isInfinite(value) || Float.isNaN(value))); 86 } 87 } 88 testCompare()89 public void testCompare() { 90 for (float x : VALUES) { 91 for (float y : VALUES) { 92 // note: spec requires only that the sign is the same 93 assertWithMessage(x + ", " + y) 94 .that(Floats.compare(x, y)) 95 .isEqualTo(Float.valueOf(x).compareTo(y)); 96 } 97 } 98 } 99 testContains()100 public void testContains() { 101 assertThat(Floats.contains(EMPTY, (float) 1)).isFalse(); 102 assertThat(Floats.contains(ARRAY1, (float) 2)).isFalse(); 103 assertThat(Floats.contains(ARRAY234, (float) 1)).isFalse(); 104 assertThat(Floats.contains(new float[] {(float) -1}, (float) -1)).isTrue(); 105 assertThat(Floats.contains(ARRAY234, (float) 2)).isTrue(); 106 assertThat(Floats.contains(ARRAY234, (float) 3)).isTrue(); 107 assertThat(Floats.contains(ARRAY234, (float) 4)).isTrue(); 108 109 for (float value : NUMBERS) { 110 assertWithMessage("" + value).that(Floats.contains(new float[] {5f, value}, value)).isTrue(); 111 } 112 assertThat(Floats.contains(new float[] {5f, NaN}, NaN)).isFalse(); 113 } 114 testIndexOf()115 public void testIndexOf() { 116 assertThat(Floats.indexOf(EMPTY, (float) 1)).isEqualTo(-1); 117 assertThat(Floats.indexOf(ARRAY1, (float) 2)).isEqualTo(-1); 118 assertThat(Floats.indexOf(ARRAY234, (float) 1)).isEqualTo(-1); 119 assertThat(Floats.indexOf(new float[] {(float) -1}, (float) -1)).isEqualTo(0); 120 assertThat(Floats.indexOf(ARRAY234, (float) 2)).isEqualTo(0); 121 assertThat(Floats.indexOf(ARRAY234, (float) 3)).isEqualTo(1); 122 assertThat(Floats.indexOf(ARRAY234, (float) 4)).isEqualTo(2); 123 assertThat(Floats.indexOf(new float[] {(float) 2, (float) 3, (float) 2, (float) 3}, (float) 3)) 124 .isEqualTo(1); 125 126 for (float value : NUMBERS) { 127 assertWithMessage("" + value) 128 .that(Floats.indexOf(new float[] {5f, value}, value)) 129 .isEqualTo(1); 130 } 131 assertThat(Floats.indexOf(new float[] {5f, NaN}, NaN)).isEqualTo(-1); 132 } 133 testIndexOf_arrayTarget()134 public void testIndexOf_arrayTarget() { 135 assertThat(Floats.indexOf(EMPTY, EMPTY)).isEqualTo(0); 136 assertThat(Floats.indexOf(ARRAY234, EMPTY)).isEqualTo(0); 137 assertThat(Floats.indexOf(EMPTY, ARRAY234)).isEqualTo(-1); 138 assertThat(Floats.indexOf(ARRAY234, ARRAY1)).isEqualTo(-1); 139 assertThat(Floats.indexOf(ARRAY1, ARRAY234)).isEqualTo(-1); 140 assertThat(Floats.indexOf(ARRAY1, ARRAY1)).isEqualTo(0); 141 assertThat(Floats.indexOf(ARRAY234, ARRAY234)).isEqualTo(0); 142 assertThat(Floats.indexOf(ARRAY234, new float[] {(float) 2, (float) 3})).isEqualTo(0); 143 assertThat(Floats.indexOf(ARRAY234, new float[] {(float) 3, (float) 4})).isEqualTo(1); 144 assertThat(Floats.indexOf(ARRAY234, new float[] {(float) 3})).isEqualTo(1); 145 assertThat(Floats.indexOf(ARRAY234, new float[] {(float) 4})).isEqualTo(2); 146 assertThat( 147 Floats.indexOf( 148 new float[] {(float) 2, (float) 3, (float) 3, (float) 3, (float) 3}, 149 new float[] {(float) 3})) 150 .isEqualTo(1); 151 assertThat( 152 Floats.indexOf( 153 new float[] { 154 (float) 2, (float) 3, (float) 2, (float) 3, (float) 4, (float) 2, (float) 3 155 }, 156 new float[] {(float) 2, (float) 3, (float) 4})) 157 .isEqualTo(2); 158 assertThat( 159 Floats.indexOf( 160 new float[] { 161 (float) 2, (float) 2, (float) 3, (float) 4, (float) 2, (float) 3, (float) 4 162 }, 163 new float[] {(float) 2, (float) 3, (float) 4})) 164 .isEqualTo(1); 165 assertThat( 166 Floats.indexOf( 167 new float[] {(float) 4, (float) 3, (float) 2}, 168 new float[] {(float) 2, (float) 3, (float) 4})) 169 .isEqualTo(-1); 170 171 for (float value : NUMBERS) { 172 assertWithMessage("" + value) 173 .that(Floats.indexOf(new float[] {5f, value, value, 5f}, new float[] {value, value})) 174 .isEqualTo(1); 175 } 176 assertThat(Floats.indexOf(new float[] {5f, NaN, NaN, 5f}, new float[] {NaN, NaN})) 177 .isEqualTo(-1); 178 } 179 testLastIndexOf()180 public void testLastIndexOf() { 181 assertThat(Floats.lastIndexOf(EMPTY, (float) 1)).isEqualTo(-1); 182 assertThat(Floats.lastIndexOf(ARRAY1, (float) 2)).isEqualTo(-1); 183 assertThat(Floats.lastIndexOf(ARRAY234, (float) 1)).isEqualTo(-1); 184 assertThat(Floats.lastIndexOf(new float[] {(float) -1}, (float) -1)).isEqualTo(0); 185 assertThat(Floats.lastIndexOf(ARRAY234, (float) 2)).isEqualTo(0); 186 assertThat(Floats.lastIndexOf(ARRAY234, (float) 3)).isEqualTo(1); 187 assertThat(Floats.lastIndexOf(ARRAY234, (float) 4)).isEqualTo(2); 188 assertThat( 189 Floats.lastIndexOf(new float[] {(float) 2, (float) 3, (float) 2, (float) 3}, (float) 3)) 190 .isEqualTo(3); 191 192 for (float value : NUMBERS) { 193 assertWithMessage("" + value) 194 .that(Floats.lastIndexOf(new float[] {value, 5f}, value)) 195 .isEqualTo(0); 196 } 197 assertThat(Floats.lastIndexOf(new float[] {NaN, 5f}, NaN)).isEqualTo(-1); 198 } 199 200 @GwtIncompatible testMax_noArgs()201 public void testMax_noArgs() { 202 try { 203 Floats.max(); 204 fail(); 205 } catch (IllegalArgumentException expected) { 206 } 207 } 208 testMax()209 public void testMax() { 210 assertThat(Floats.max(GREATEST)).isEqualTo(GREATEST); 211 assertThat(Floats.max(LEAST)).isEqualTo(LEAST); 212 assertThat( 213 Floats.max((float) 8, (float) 6, (float) 7, (float) 5, (float) 3, (float) 0, (float) 9)) 214 .isEqualTo((float) 9); 215 216 assertThat(Floats.max(-0f, 0f)).isEqualTo(0f); 217 assertThat(Floats.max(0f, -0f)).isEqualTo(0f); 218 assertThat(Floats.max(NUMBERS)).isEqualTo(GREATEST); 219 assertThat(Float.isNaN(Floats.max(VALUES))).isTrue(); 220 } 221 222 @GwtIncompatible testMin_noArgs()223 public void testMin_noArgs() { 224 try { 225 Floats.min(); 226 fail(); 227 } catch (IllegalArgumentException expected) { 228 } 229 } 230 testMin()231 public void testMin() { 232 assertThat(Floats.min(LEAST)).isEqualTo(LEAST); 233 assertThat(Floats.min(GREATEST)).isEqualTo(GREATEST); 234 assertThat( 235 Floats.min((float) 8, (float) 6, (float) 7, (float) 5, (float) 3, (float) 0, (float) 9)) 236 .isEqualTo((float) 0); 237 238 assertThat(Floats.min(-0f, 0f)).isEqualTo(-0f); 239 assertThat(Floats.min(0f, -0f)).isEqualTo(-0f); 240 assertThat(Floats.min(NUMBERS)).isEqualTo(LEAST); 241 assertThat(Float.isNaN(Floats.min(VALUES))).isTrue(); 242 } 243 testConstrainToRange()244 public void testConstrainToRange() { 245 assertThat(Floats.constrainToRange((float) 1, (float) 0, (float) 5)).isEqualTo((float) 1); 246 assertThat(Floats.constrainToRange((float) 1, (float) 1, (float) 5)).isEqualTo((float) 1); 247 assertThat(Floats.constrainToRange((float) 1, (float) 3, (float) 5)).isEqualTo((float) 3); 248 assertThat(Floats.constrainToRange((float) 0, (float) -5, (float) -1)).isEqualTo((float) -1); 249 assertThat(Floats.constrainToRange((float) 5, (float) 2, (float) 2)).isEqualTo((float) 2); 250 try { 251 Floats.constrainToRange((float) 1, (float) 3, (float) 2); 252 fail(); 253 } catch (IllegalArgumentException expected) { 254 } 255 } 256 testConcat()257 public void testConcat() { 258 assertThat(Floats.concat()).isEqualTo(EMPTY); 259 assertThat(Floats.concat(EMPTY)).isEqualTo(EMPTY); 260 assertThat(Floats.concat(EMPTY, EMPTY, EMPTY)).isEqualTo(EMPTY); 261 assertThat(Floats.concat(ARRAY1)).isEqualTo(ARRAY1); 262 assertThat(Floats.concat(ARRAY1)).isNotSameInstanceAs(ARRAY1); 263 assertThat(Floats.concat(EMPTY, ARRAY1, EMPTY)).isEqualTo(ARRAY1); 264 assertThat(Floats.concat(ARRAY1, ARRAY1, ARRAY1)) 265 .isEqualTo(new float[] {(float) 1, (float) 1, (float) 1}); 266 assertThat(Floats.concat(ARRAY1, ARRAY234)) 267 .isEqualTo(new float[] {(float) 1, (float) 2, (float) 3, (float) 4}); 268 } 269 270 @GwtIncompatible // different overflow behavior; could probably be made to work by using ~~ testConcat_overflow_negative()271 public void testConcat_overflow_negative() { 272 int dim1 = 1 << 16; 273 int dim2 = 1 << 15; 274 assertThat(dim1 * dim2).isLessThan(0); 275 testConcatOverflow(dim1, dim2); 276 } 277 278 @GwtIncompatible // different overflow behavior; could probably be made to work by using ~~ testConcat_overflow_nonNegative()279 public void testConcat_overflow_nonNegative() { 280 int dim1 = 1 << 16; 281 int dim2 = 1 << 16; 282 assertThat(dim1 * dim2).isAtLeast(0); 283 testConcatOverflow(dim1, dim2); 284 } 285 testConcatOverflow(int arraysDim1, int arraysDim2)286 private static void testConcatOverflow(int arraysDim1, int arraysDim2) { 287 assertThat((long) arraysDim1 * arraysDim2).isNotEqualTo((long) (arraysDim1 * arraysDim2)); 288 289 float[][] arrays = new float[arraysDim1][]; 290 // it's shared to avoid using too much memory in tests 291 float[] sharedArray = new float[arraysDim2]; 292 Arrays.fill(arrays, sharedArray); 293 294 try { 295 Floats.concat(arrays); 296 fail(); 297 } catch (IllegalArgumentException expected) { 298 } 299 } 300 testEnsureCapacity()301 public void testEnsureCapacity() { 302 assertThat(Floats.ensureCapacity(EMPTY, 0, 1)).isSameInstanceAs(EMPTY); 303 assertThat(Floats.ensureCapacity(ARRAY1, 0, 1)).isSameInstanceAs(ARRAY1); 304 assertThat(Floats.ensureCapacity(ARRAY1, 1, 1)).isSameInstanceAs(ARRAY1); 305 assertThat( 306 Arrays.equals( 307 new float[] {(float) 1, (float) 0, (float) 0}, Floats.ensureCapacity(ARRAY1, 2, 1))) 308 .isTrue(); 309 } 310 testEnsureCapacity_fail()311 public void testEnsureCapacity_fail() { 312 try { 313 Floats.ensureCapacity(ARRAY1, -1, 1); 314 fail(); 315 } catch (IllegalArgumentException expected) { 316 } 317 try { 318 // notice that this should even fail when no growth was needed 319 Floats.ensureCapacity(ARRAY1, 1, -1); 320 fail(); 321 } catch (IllegalArgumentException expected) { 322 } 323 } 324 325 @GwtIncompatible // Float.toString returns different value in GWT. testJoin()326 public void testJoin() { 327 assertThat(Floats.join(",", EMPTY)).isEmpty(); 328 assertThat(Floats.join(",", ARRAY1)).isEqualTo("1.0"); 329 assertThat(Floats.join(",", (float) 1, (float) 2)).isEqualTo("1.0,2.0"); 330 assertThat(Floats.join("", (float) 1, (float) 2, (float) 3)).isEqualTo("1.02.03.0"); 331 } 332 testLexicographicalComparator()333 public void testLexicographicalComparator() { 334 List<float[]> ordered = 335 Arrays.asList( 336 new float[] {}, 337 new float[] {LEAST}, 338 new float[] {LEAST, LEAST}, 339 new float[] {LEAST, (float) 1}, 340 new float[] {(float) 1}, 341 new float[] {(float) 1, LEAST}, 342 new float[] {GREATEST, Float.MAX_VALUE}, 343 new float[] {GREATEST, GREATEST}, 344 new float[] {GREATEST, GREATEST, GREATEST}); 345 346 Comparator<float[]> comparator = Floats.lexicographicalComparator(); 347 Helpers.testComparator(comparator, ordered); 348 } 349 350 @J2ktIncompatible 351 @GwtIncompatible // SerializableTester testLexicographicalComparatorSerializable()352 public void testLexicographicalComparatorSerializable() { 353 Comparator<float[]> comparator = Floats.lexicographicalComparator(); 354 assertThat(SerializableTester.reserialize(comparator)).isSameInstanceAs(comparator); 355 } 356 testReverse()357 public void testReverse() { 358 testReverse(new float[] {}, new float[] {}); 359 testReverse(new float[] {1}, new float[] {1}); 360 testReverse(new float[] {1, 2}, new float[] {2, 1}); 361 testReverse(new float[] {3, 1, 1}, new float[] {1, 1, 3}); 362 testReverse(new float[] {-1, 1, -2, 2}, new float[] {2, -2, 1, -1}); 363 } 364 testReverse(float[] input, float[] expectedOutput)365 private static void testReverse(float[] input, float[] expectedOutput) { 366 input = Arrays.copyOf(input, input.length); 367 Floats.reverse(input); 368 assertThat(input).isEqualTo(expectedOutput); 369 } 370 testReverse( float[] input, int fromIndex, int toIndex, float[] expectedOutput)371 private static void testReverse( 372 float[] input, int fromIndex, int toIndex, float[] expectedOutput) { 373 input = Arrays.copyOf(input, input.length); 374 Floats.reverse(input, fromIndex, toIndex); 375 assertThat(input).isEqualTo(expectedOutput); 376 } 377 testReverseIndexed()378 public void testReverseIndexed() { 379 testReverse(new float[] {}, 0, 0, new float[] {}); 380 testReverse(new float[] {1}, 0, 1, new float[] {1}); 381 testReverse(new float[] {1, 2}, 0, 2, new float[] {2, 1}); 382 testReverse(new float[] {3, 1, 1}, 0, 2, new float[] {1, 3, 1}); 383 testReverse(new float[] {3, 1, 1}, 0, 1, new float[] {3, 1, 1}); 384 testReverse(new float[] {-1, 1, -2, 2}, 1, 3, new float[] {-1, -2, 1, 2}); 385 } 386 testRotate(float[] input, int distance, float[] expectedOutput)387 private static void testRotate(float[] input, int distance, float[] expectedOutput) { 388 input = Arrays.copyOf(input, input.length); 389 Floats.rotate(input, distance); 390 assertThat(input).isEqualTo(expectedOutput); 391 } 392 testRotate( float[] input, int distance, int fromIndex, int toIndex, float[] expectedOutput)393 private static void testRotate( 394 float[] input, int distance, int fromIndex, int toIndex, float[] expectedOutput) { 395 input = Arrays.copyOf(input, input.length); 396 Floats.rotate(input, distance, fromIndex, toIndex); 397 assertThat(input).isEqualTo(expectedOutput); 398 } 399 testRotate()400 public void testRotate() { 401 testRotate(new float[] {}, -1, new float[] {}); 402 testRotate(new float[] {}, 0, new float[] {}); 403 testRotate(new float[] {}, 1, new float[] {}); 404 405 testRotate(new float[] {1}, -2, new float[] {1}); 406 testRotate(new float[] {1}, -1, new float[] {1}); 407 testRotate(new float[] {1}, 0, new float[] {1}); 408 testRotate(new float[] {1}, 1, new float[] {1}); 409 testRotate(new float[] {1}, 2, new float[] {1}); 410 411 testRotate(new float[] {1, 2}, -3, new float[] {2, 1}); 412 testRotate(new float[] {1, 2}, -1, new float[] {2, 1}); 413 testRotate(new float[] {1, 2}, -2, new float[] {1, 2}); 414 testRotate(new float[] {1, 2}, 0, new float[] {1, 2}); 415 testRotate(new float[] {1, 2}, 1, new float[] {2, 1}); 416 testRotate(new float[] {1, 2}, 2, new float[] {1, 2}); 417 testRotate(new float[] {1, 2}, 3, new float[] {2, 1}); 418 419 testRotate(new float[] {1, 2, 3}, -5, new float[] {3, 1, 2}); 420 testRotate(new float[] {1, 2, 3}, -4, new float[] {2, 3, 1}); 421 testRotate(new float[] {1, 2, 3}, -3, new float[] {1, 2, 3}); 422 testRotate(new float[] {1, 2, 3}, -2, new float[] {3, 1, 2}); 423 testRotate(new float[] {1, 2, 3}, -1, new float[] {2, 3, 1}); 424 testRotate(new float[] {1, 2, 3}, 0, new float[] {1, 2, 3}); 425 testRotate(new float[] {1, 2, 3}, 1, new float[] {3, 1, 2}); 426 testRotate(new float[] {1, 2, 3}, 2, new float[] {2, 3, 1}); 427 testRotate(new float[] {1, 2, 3}, 3, new float[] {1, 2, 3}); 428 testRotate(new float[] {1, 2, 3}, 4, new float[] {3, 1, 2}); 429 testRotate(new float[] {1, 2, 3}, 5, new float[] {2, 3, 1}); 430 431 testRotate(new float[] {1, 2, 3, 4}, -9, new float[] {2, 3, 4, 1}); 432 testRotate(new float[] {1, 2, 3, 4}, -5, new float[] {2, 3, 4, 1}); 433 testRotate(new float[] {1, 2, 3, 4}, -1, new float[] {2, 3, 4, 1}); 434 testRotate(new float[] {1, 2, 3, 4}, 0, new float[] {1, 2, 3, 4}); 435 testRotate(new float[] {1, 2, 3, 4}, 1, new float[] {4, 1, 2, 3}); 436 testRotate(new float[] {1, 2, 3, 4}, 5, new float[] {4, 1, 2, 3}); 437 testRotate(new float[] {1, 2, 3, 4}, 9, new float[] {4, 1, 2, 3}); 438 439 testRotate(new float[] {1, 2, 3, 4, 5}, -6, new float[] {2, 3, 4, 5, 1}); 440 testRotate(new float[] {1, 2, 3, 4, 5}, -4, new float[] {5, 1, 2, 3, 4}); 441 testRotate(new float[] {1, 2, 3, 4, 5}, -3, new float[] {4, 5, 1, 2, 3}); 442 testRotate(new float[] {1, 2, 3, 4, 5}, -1, new float[] {2, 3, 4, 5, 1}); 443 testRotate(new float[] {1, 2, 3, 4, 5}, 0, new float[] {1, 2, 3, 4, 5}); 444 testRotate(new float[] {1, 2, 3, 4, 5}, 1, new float[] {5, 1, 2, 3, 4}); 445 testRotate(new float[] {1, 2, 3, 4, 5}, 3, new float[] {3, 4, 5, 1, 2}); 446 testRotate(new float[] {1, 2, 3, 4, 5}, 4, new float[] {2, 3, 4, 5, 1}); 447 testRotate(new float[] {1, 2, 3, 4, 5}, 6, new float[] {5, 1, 2, 3, 4}); 448 } 449 testRotateIndexed()450 public void testRotateIndexed() { 451 testRotate(new float[] {}, 0, 0, 0, new float[] {}); 452 453 testRotate(new float[] {1}, 0, 0, 1, new float[] {1}); 454 testRotate(new float[] {1}, 1, 0, 1, new float[] {1}); 455 testRotate(new float[] {1}, 1, 1, 1, new float[] {1}); 456 457 // Rotate the central 5 elements, leaving the ends as-is 458 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -6, 1, 6, new float[] {0, 2, 3, 4, 5, 1, 6}); 459 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -1, 1, 6, new float[] {0, 2, 3, 4, 5, 1, 6}); 460 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 0, 1, 6, new float[] {0, 1, 2, 3, 4, 5, 6}); 461 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 5, 1, 6, new float[] {0, 1, 2, 3, 4, 5, 6}); 462 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 14, 1, 6, new float[] {0, 2, 3, 4, 5, 1, 6}); 463 464 // Rotate the first three elements 465 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -2, 0, 3, new float[] {2, 0, 1, 3, 4, 5, 6}); 466 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -1, 0, 3, new float[] {1, 2, 0, 3, 4, 5, 6}); 467 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 0, 0, 3, new float[] {0, 1, 2, 3, 4, 5, 6}); 468 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 1, 0, 3, new float[] {2, 0, 1, 3, 4, 5, 6}); 469 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 2, 0, 3, new float[] {1, 2, 0, 3, 4, 5, 6}); 470 471 // Rotate the last four elements 472 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -6, 3, 7, new float[] {0, 1, 2, 5, 6, 3, 4}); 473 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -5, 3, 7, new float[] {0, 1, 2, 4, 5, 6, 3}); 474 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -4, 3, 7, new float[] {0, 1, 2, 3, 4, 5, 6}); 475 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -3, 3, 7, new float[] {0, 1, 2, 6, 3, 4, 5}); 476 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -2, 3, 7, new float[] {0, 1, 2, 5, 6, 3, 4}); 477 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, -1, 3, 7, new float[] {0, 1, 2, 4, 5, 6, 3}); 478 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 0, 3, 7, new float[] {0, 1, 2, 3, 4, 5, 6}); 479 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 1, 3, 7, new float[] {0, 1, 2, 6, 3, 4, 5}); 480 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 2, 3, 7, new float[] {0, 1, 2, 5, 6, 3, 4}); 481 testRotate(new float[] {0, 1, 2, 3, 4, 5, 6}, 3, 3, 7, new float[] {0, 1, 2, 4, 5, 6, 3}); 482 } 483 testSortDescending()484 public void testSortDescending() { 485 testSortDescending(new float[] {}, new float[] {}); 486 testSortDescending(new float[] {1}, new float[] {1}); 487 testSortDescending(new float[] {1, 2}, new float[] {2, 1}); 488 testSortDescending(new float[] {1, 3, 1}, new float[] {3, 1, 1}); 489 testSortDescending(new float[] {-1, 1, -2, 2}, new float[] {2, 1, -1, -2}); 490 testSortDescending( 491 new float[] {-1, 1, Float.NaN, -2, -0f, 0, 2}, 492 new float[] {Float.NaN, 2, 1, 0, -0f, -1, -2}); 493 } 494 testSortDescending(float[] input, float[] expectedOutput)495 private static void testSortDescending(float[] input, float[] expectedOutput) { 496 input = Arrays.copyOf(input, input.length); 497 Floats.sortDescending(input); 498 for (int i = 0; i < input.length; i++) { 499 assertThat(input[i]).isEqualTo(expectedOutput[i]); 500 } 501 } 502 testSortDescending( float[] input, int fromIndex, int toIndex, float[] expectedOutput)503 private static void testSortDescending( 504 float[] input, int fromIndex, int toIndex, float[] expectedOutput) { 505 input = Arrays.copyOf(input, input.length); 506 Floats.sortDescending(input, fromIndex, toIndex); 507 for (int i = 0; i < input.length; i++) { 508 assertThat(input[i]).isEqualTo(expectedOutput[i]); 509 } 510 } 511 testSortDescendingIndexed()512 public void testSortDescendingIndexed() { 513 testSortDescending(new float[] {}, 0, 0, new float[] {}); 514 testSortDescending(new float[] {1}, 0, 1, new float[] {1}); 515 testSortDescending(new float[] {1, 2}, 0, 2, new float[] {2, 1}); 516 testSortDescending(new float[] {1, 3, 1}, 0, 2, new float[] {3, 1, 1}); 517 testSortDescending(new float[] {1, 3, 1}, 0, 1, new float[] {1, 3, 1}); 518 testSortDescending(new float[] {-1, -2, 1, 2}, 1, 3, new float[] {-1, 1, -2, 2}); 519 testSortDescending( 520 new float[] {-1, 1, Float.NaN, -2, 2}, 1, 4, new float[] {-1, Float.NaN, 1, -2, 2}); 521 } 522 523 @J2ktIncompatible 524 @GwtIncompatible // SerializableTester testStringConverterSerialization()525 public void testStringConverterSerialization() { 526 SerializableTester.reserializeAndAssert(Floats.stringConverter()); 527 } 528 testToArray()529 public void testToArray() { 530 // need explicit type parameter to avoid javac warning!? 531 List<Float> none = Arrays.<Float>asList(); 532 assertThat(Floats.toArray(none)).isEqualTo(EMPTY); 533 534 List<Float> one = Arrays.asList((float) 1); 535 assertThat(Floats.toArray(one)).isEqualTo(ARRAY1); 536 537 float[] array = {(float) 0, (float) 1, (float) 3}; 538 539 List<Float> three = Arrays.asList((float) 0, (float) 1, (float) 3); 540 assertThat(Floats.toArray(three)).isEqualTo(array); 541 542 assertThat(Floats.toArray(Floats.asList(array))).isEqualTo(array); 543 } 544 testToArray_threadSafe()545 public void testToArray_threadSafe() { 546 for (int delta : new int[] {+1, 0, -1}) { 547 for (int i = 0; i < VALUES.length; i++) { 548 List<Float> list = Floats.asList(VALUES).subList(0, i); 549 Collection<Float> misleadingSize = Helpers.misleadingSizeCollection(delta); 550 misleadingSize.addAll(list); 551 float[] arr = Floats.toArray(misleadingSize); 552 assertThat(arr.length).isEqualTo(i); 553 for (int j = 0; j < i; j++) { 554 assertThat(arr[j]).isEqualTo(VALUES[j]); 555 } 556 } 557 } 558 } 559 testToArray_withNull()560 public void testToArray_withNull() { 561 List<@Nullable Float> list = Arrays.asList((float) 0, (float) 1, null); 562 try { 563 Floats.toArray(list); 564 fail(); 565 } catch (NullPointerException expected) { 566 } 567 } 568 testToArray_withConversion()569 public void testToArray_withConversion() { 570 float[] array = {(float) 0, (float) 1, (float) 2}; 571 572 List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2); 573 List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2); 574 List<Integer> ints = Arrays.asList(0, 1, 2); 575 List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2); 576 List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2); 577 List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2); 578 579 assertThat(Floats.toArray(bytes)).isEqualTo(array); 580 assertThat(Floats.toArray(shorts)).isEqualTo(array); 581 assertThat(Floats.toArray(ints)).isEqualTo(array); 582 assertThat(Floats.toArray(floats)).isEqualTo(array); 583 assertThat(Floats.toArray(longs)).isEqualTo(array); 584 assertThat(Floats.toArray(doubles)).isEqualTo(array); 585 } 586 587 @J2ktIncompatible // b/239034072: Kotlin varargs copy parameter arrays. testAsList_isAView()588 public void testAsList_isAView() { 589 float[] array = {(float) 0, (float) 1}; 590 List<Float> list = Floats.asList(array); 591 list.set(0, (float) 2); 592 assertThat(array).isEqualTo(new float[] {(float) 2, (float) 1}); 593 array[1] = (float) 3; 594 assertThat(list).containsExactly((float) 2, (float) 3).inOrder(); 595 } 596 testAsList_toArray_roundTrip()597 public void testAsList_toArray_roundTrip() { 598 float[] array = {(float) 0, (float) 1, (float) 2}; 599 List<Float> list = Floats.asList(array); 600 float[] newArray = Floats.toArray(list); 601 602 // Make sure it returned a copy 603 list.set(0, (float) 4); 604 assertThat(newArray).isEqualTo(new float[] {(float) 0, (float) 1, (float) 2}); 605 newArray[1] = (float) 5; 606 assertThat((float) list.get(1)).isEqualTo((float) 1); 607 } 608 609 // This test stems from a real bug found by andrewk testAsList_subList_toArray_roundTrip()610 public void testAsList_subList_toArray_roundTrip() { 611 float[] array = {(float) 0, (float) 1, (float) 2, (float) 3}; 612 List<Float> list = Floats.asList(array); 613 assertThat(Floats.toArray(list.subList(1, 3))).isEqualTo(new float[] {(float) 1, (float) 2}); 614 assertThat(Floats.toArray(list.subList(2, 2))).isEmpty(); 615 } 616 testAsListEmpty()617 public void testAsListEmpty() { 618 assertThat(Floats.asList(EMPTY)).isSameInstanceAs(Collections.emptyList()); 619 } 620 621 /** 622 * A reference implementation for {@code tryParse} that just catches the exception from {@link 623 * Float#valueOf}. 624 */ referenceTryParse(String input)625 private static @Nullable Float referenceTryParse(String input) { 626 if (input.trim().length() < input.length()) { 627 return null; 628 } 629 try { 630 return Float.valueOf(input); 631 } catch (NumberFormatException e) { 632 return null; 633 } 634 } 635 636 @GwtIncompatible // Floats.tryParse checkTryParse(String input)637 private static void checkTryParse(String input) { 638 assertThat(Floats.tryParse(input)).isEqualTo(referenceTryParse(input)); 639 } 640 641 @GwtIncompatible // Floats.tryParse checkTryParse(float expected, String input)642 private static void checkTryParse(float expected, String input) { 643 assertThat(Floats.tryParse(input)).isEqualTo(Float.valueOf(expected)); 644 } 645 646 @GwtIncompatible // Floats.tryParse testTryParseHex()647 public void testTryParseHex() { 648 for (String signChar : ImmutableList.of("", "+", "-")) { 649 for (String hexPrefix : ImmutableList.of("0x", "0X")) { 650 for (String iPart : ImmutableList.of("", "0", "1", "F", "f", "c4", "CE")) { 651 for (String fPart : ImmutableList.of("", ".", ".F", ".52", ".a")) { 652 for (String expMarker : ImmutableList.of("p", "P")) { 653 for (String exponent : ImmutableList.of("0", "-5", "+20", "52")) { 654 for (String typePart : ImmutableList.of("", "D", "F", "d", "f")) { 655 checkTryParse( 656 signChar + hexPrefix + iPart + fPart + expMarker + exponent + typePart); 657 } 658 } 659 } 660 } 661 } 662 } 663 } 664 } 665 666 @AndroidIncompatible // slow 667 @GwtIncompatible // Floats.tryParse testTryParseAllCodePoints()668 public void testTryParseAllCodePoints() { 669 // Exercise non-ASCII digit test cases and the like. 670 char[] tmp = new char[2]; 671 for (int i = Character.MIN_CODE_POINT; i < Character.MAX_CODE_POINT; i++) { 672 Character.toChars(i, tmp, 0); 673 checkTryParse(String.copyValueOf(tmp, 0, Character.charCount(i))); 674 } 675 } 676 677 @GwtIncompatible // Floats.tryParse testTryParseOfToStringIsOriginal()678 public void testTryParseOfToStringIsOriginal() { 679 for (float f : NUMBERS) { 680 checkTryParse(f, Float.toString(f)); 681 } 682 } 683 684 @J2ktIncompatible // hexadecimal floats 685 @GwtIncompatible // Floats.tryParse testTryParseOfToHexStringIsOriginal()686 public void testTryParseOfToHexStringIsOriginal() { 687 for (float f : NUMBERS) { 688 checkTryParse(f, Float.toHexString(f)); 689 } 690 } 691 692 @GwtIncompatible // Floats.tryParse testTryParseNaN()693 public void testTryParseNaN() { 694 checkTryParse("NaN"); 695 checkTryParse("+NaN"); 696 checkTryParse("-NaN"); 697 } 698 699 @GwtIncompatible // Floats.tryParse testTryParseInfinity()700 public void testTryParseInfinity() { 701 checkTryParse(Float.POSITIVE_INFINITY, "Infinity"); 702 checkTryParse(Float.POSITIVE_INFINITY, "+Infinity"); 703 checkTryParse(Float.NEGATIVE_INFINITY, "-Infinity"); 704 } 705 706 private static final String[] BAD_TRY_PARSE_INPUTS = { 707 "", 708 "+-", 709 "+-0", 710 " 5", 711 "32 ", 712 " 55 ", 713 "infinity", 714 "POSITIVE_INFINITY", 715 "0x9A", 716 "0x9A.bE-5", 717 ".", 718 ".e5", 719 "NaNd", 720 "InfinityF" 721 }; 722 723 @GwtIncompatible // Floats.tryParse testTryParseFailures()724 public void testTryParseFailures() { 725 for (String badInput : BAD_TRY_PARSE_INPUTS) { 726 assertThat(Floats.tryParse(badInput)).isEqualTo(referenceTryParse(badInput)); 727 assertThat(Floats.tryParse(badInput)).isNull(); 728 } 729 } 730 731 @J2ktIncompatible 732 @GwtIncompatible // NullPointerTester testNulls()733 public void testNulls() { 734 new NullPointerTester().testAllPublicStaticMethods(Floats.class); 735 } 736 737 @GwtIncompatible // Float.toString returns different value in GWT. testStringConverter_convert()738 public void testStringConverter_convert() { 739 Converter<String, Float> converter = Floats.stringConverter(); 740 assertThat(converter.convert("1.0")).isEqualTo((Float) 1.0f); 741 assertThat(converter.convert("0.0")).isEqualTo((Float) 0.0f); 742 assertThat(converter.convert("-1.0")).isEqualTo((Float) (-1.0f)); 743 assertThat(converter.convert("1")).isEqualTo((Float) 1.0f); 744 assertThat(converter.convert("0")).isEqualTo((Float) 0.0f); 745 assertThat(converter.convert("-1")).isEqualTo((Float) (-1.0f)); 746 assertThat(converter.convert("1e6")).isEqualTo((Float) 1e6f); 747 assertThat(converter.convert("1e-6")).isEqualTo((Float) 1e-6f); 748 } 749 testStringConverter_convertError()750 public void testStringConverter_convertError() { 751 try { 752 Floats.stringConverter().convert("notanumber"); 753 fail(); 754 } catch (NumberFormatException expected) { 755 } 756 } 757 testStringConverter_nullConversions()758 public void testStringConverter_nullConversions() { 759 assertThat(Floats.stringConverter().convert(null)).isNull(); 760 assertThat(Floats.stringConverter().reverse().convert(null)).isNull(); 761 } 762 763 @J2ktIncompatible 764 @GwtIncompatible // Float.toString returns different value in GWT. testStringConverter_reverse()765 public void testStringConverter_reverse() { 766 Converter<String, Float> converter = Floats.stringConverter(); 767 assertThat(converter.reverse().convert(1.0f)).isEqualTo("1.0"); 768 assertThat(converter.reverse().convert(0.0f)).isEqualTo("0.0"); 769 assertThat(converter.reverse().convert(-1.0f)).isEqualTo("-1.0"); 770 assertThat(converter.reverse().convert(1e6f)).isEqualTo("1000000.0"); 771 assertThat(converter.reverse().convert(1e-6f)).isEqualTo("1.0E-6"); 772 } 773 774 @J2ktIncompatible 775 @GwtIncompatible // NullPointerTester testStringConverter_nullPointerTester()776 public void testStringConverter_nullPointerTester() throws Exception { 777 NullPointerTester tester = new NullPointerTester(); 778 tester.testAllPublicInstanceMethods(Floats.stringConverter()); 779 } 780 781 @GwtIncompatible testTryParse_withNullNoGwt()782 public void testTryParse_withNullNoGwt() { 783 assertThat(Floats.tryParse("null")).isNull(); 784 try { 785 Floats.tryParse(null); 786 fail("Expected NPE"); 787 } catch (NullPointerException expected) { 788 } 789 } 790 } 791