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