View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.numbers.fraction;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.List;
22  
23  /**
24   * A collection of test cases that can be applied both to {@link Fraction}
25   * and {@link BigFraction}, e.g. for operations and expected results that
26   * involve numerators and denominators in the {@code int} range.
27   */
28  final class CommonTestCases {
29  
30      /**
31       * See {@link #numDenConstructorTestCases()}
32       */
33      private static final List<UnaryOperatorTestCase> numDenConstructorTestCasesList;
34  
35      /**
36       * See {@link #doubleConstructorTestCases()}
37       */
38      private static final List<DoubleToFractionTestCase> doubleConstructorTestCasesList;
39  
40      /**
41       * See {@link #doubleMaxDenomConstructorTestCases()}
42       */
43      private static final List<DoubleToFractionTestCase> doubleMaxDenomConstructorTestCasesList;
44  
45      /**
46       * See {@link #absTestCases()}
47       */
48      private static final List<UnaryOperatorTestCase> absTestCasesList;
49  
50      /**
51       * See {@link #reciprocalTestCases()}
52       */
53      private static final List<UnaryOperatorTestCase> reciprocalTestCasesList;
54  
55      /**
56       * See {@link #negateTestCases()}
57       */
58      private static final List<UnaryOperatorTestCase> negateTestCasesList;
59  
60      /**
61       * See {@link #addFractionTestCases()}
62       */
63      private static final List<BinaryOperatorTestCase> addFractionTestCasesList;
64  
65      /**
66       * See {@link #addIntTestCases()}
67       */
68      private static final List<BinaryIntOperatorTestCase> addIntTestCasesList;
69  
70      /**
71       * See {@link #divideByFractionTestCases()}
72       */
73      private static final List<BinaryOperatorTestCase> divideByFractionTestCasesList;
74  
75      /**
76       * See {@link #divideByIntTestCases()}
77       */
78      private static final List<BinaryIntOperatorTestCase> divideByIntTestCasesList;
79  
80      /**
81       * See {@link #multiplyByFractionTestCases()}
82       */
83      private static final List<BinaryOperatorTestCase> multiplyByFractionTestCasesList;
84  
85      /**
86       * See {@link #multiplyByIntTestCases()}
87       */
88      private static final List<BinaryIntOperatorTestCase> multiplyByIntTestCasesList;
89  
90      /**
91       * See {@link #subtractFractionTestCases()}
92       */
93      private static final List<BinaryOperatorTestCase> subtractFractionTestCasesList;
94  
95      /**
96       * See {@link #subtractIntTestCases()}
97       */
98      private static final List<BinaryIntOperatorTestCase> subtractIntTestCasesList;
99  
100     /**
101      * See {@link #powTestCases()}
102      */
103     private static final List<BinaryIntOperatorTestCase> powTestCasesList;
104 
105     static {
106         numDenConstructorTestCasesList = collectNumDenConstructorTestCases();
107         doubleConstructorTestCasesList = collectDoubleConstructorTestCases();
108         doubleMaxDenomConstructorTestCasesList = collectDoubleMaxDenomConstructorTestCases();
109         absTestCasesList = collectAbsTestCases();
110         reciprocalTestCasesList = collectReciprocalTestCases();
111         negateTestCasesList = collectNegateTestCases();
112         addFractionTestCasesList = collectAddFractionTestCases();
113         addIntTestCasesList = collectAddIntTestCases();
114         divideByFractionTestCasesList = collectDivideByFractionTestCases();
115         divideByIntTestCasesList = collectDivideByIntTestCases();
116         multiplyByFractionTestCasesList = collectMultiplyByFractionTestCases();
117         multiplyByIntTestCasesList = collectMultiplyByIntTestCases();
118         subtractFractionTestCasesList = collectSubtractFractionTestCases();
119         subtractIntTestCasesList = collectSubtractIntTestCases();
120         powTestCasesList = collectPowTestCases();
121     }
122 
123     private CommonTestCases() {}
124 
125     /**
126      * Defines test cases as described in
127      * {@link #numDenConstructorTestCases()} and collects them into a {@code
128      * List}.
129      * @return a list of test cases as described above
130      */
131     private static List<UnaryOperatorTestCase> collectNumDenConstructorTestCases() {
132         final List<UnaryOperatorTestCase> testCases = new ArrayList<>();
133 
134         testCases.add(new UnaryOperatorTestCase(0, 1, 0, 1));
135         testCases.add(new UnaryOperatorTestCase(0, 2, 0, 1));
136         testCases.add(new UnaryOperatorTestCase(0, -1, 0, 1));
137         testCases.add(new UnaryOperatorTestCase(1, 2, 1, 2));
138         testCases.add(new UnaryOperatorTestCase(2, 4, 1, 2));
139         testCases.add(new UnaryOperatorTestCase(-1, 2, -1, 2));
140         testCases.add(new UnaryOperatorTestCase(1, -2, 1, -2));
141         testCases.add(new UnaryOperatorTestCase(-2, 4, -1, 2));
142         testCases.add(new UnaryOperatorTestCase(2, -4, 1, -2));
143         testCases.add(new UnaryOperatorTestCase(-2, -4, -1, -2));
144 
145         testCases.add(new UnaryOperatorTestCase(2, Integer.MIN_VALUE, 1, Integer.MIN_VALUE / 2));
146         testCases.add(new UnaryOperatorTestCase(Integer.MIN_VALUE, -2, -Integer.MIN_VALUE / 2, -1));
147 
148         return testCases;
149     }
150 
151     /**
152      * Defines test cases as described in
153      * {@link #doubleConstructorTestCases()} and collects them into a {@code List}.
154      * @return a list of test cases as described above
155      */
156     private static List<DoubleToFractionTestCase> collectDoubleConstructorTestCases() {
157         final List<DoubleToFractionTestCase> testCases = new ArrayList<>();
158 
159         testCases.add(new DoubleToFractionTestCase(1d / 2d, 1, 2));
160         testCases.add(new DoubleToFractionTestCase(1d / 3d, 1, 3));
161         testCases.add(new DoubleToFractionTestCase(2d / 3d, 2, 3));
162         testCases.add(new DoubleToFractionTestCase(1d / 4d, 1, 4));
163         testCases.add(new DoubleToFractionTestCase(3d / 4d, 3, 4));
164         testCases.add(new DoubleToFractionTestCase(1d / 5d, 1, 5));
165         testCases.add(new DoubleToFractionTestCase(2d / 5d, 2, 5));
166         testCases.add(new DoubleToFractionTestCase(3d / 5d, 3, 5));
167         testCases.add(new DoubleToFractionTestCase(4d / 5d, 4, 5));
168         testCases.add(new DoubleToFractionTestCase(1d / 6d, 1, 6));
169         testCases.add(new DoubleToFractionTestCase(5d / 6d, 5, 6));
170         testCases.add(new DoubleToFractionTestCase(1d / 7d, 1, 7));
171         testCases.add(new DoubleToFractionTestCase(2d / 7d, 2, 7));
172         testCases.add(new DoubleToFractionTestCase(3d / 7d, 3, 7));
173         testCases.add(new DoubleToFractionTestCase(4d / 7d, 4, 7));
174         testCases.add(new DoubleToFractionTestCase(5d / 7d, 5, 7));
175         testCases.add(new DoubleToFractionTestCase(6d / 7d, 6, 7));
176         testCases.add(new DoubleToFractionTestCase(1d / 8d, 1, 8));
177         testCases.add(new DoubleToFractionTestCase(3d / 8d, 3, 8));
178         testCases.add(new DoubleToFractionTestCase(5d / 8d, 5, 8));
179         testCases.add(new DoubleToFractionTestCase(7d / 8d, 7, 8));
180         testCases.add(new DoubleToFractionTestCase(1d / 9d, 1, 9));
181         testCases.add(new DoubleToFractionTestCase(2d / 9d, 2, 9));
182         testCases.add(new DoubleToFractionTestCase(4d / 9d, 4, 9));
183         testCases.add(new DoubleToFractionTestCase(5d / 9d, 5, 9));
184         testCases.add(new DoubleToFractionTestCase(7d / 9d, 7, 9));
185         testCases.add(new DoubleToFractionTestCase(8d / 9d, 8, 9));
186         testCases.add(new DoubleToFractionTestCase(1d / 10d, 1, 10));
187         testCases.add(new DoubleToFractionTestCase(3d / 10d, 3, 10));
188         testCases.add(new DoubleToFractionTestCase(7d / 10d, 7, 10));
189         testCases.add(new DoubleToFractionTestCase(9d / 10d, 9, 10));
190         testCases.add(new DoubleToFractionTestCase(1d / 11d, 1, 11));
191         testCases.add(new DoubleToFractionTestCase(2d / 11d, 2, 11));
192         testCases.add(new DoubleToFractionTestCase(3d / 11d, 3, 11));
193         testCases.add(new DoubleToFractionTestCase(4d / 11d, 4, 11));
194         testCases.add(new DoubleToFractionTestCase(5d / 11d, 5, 11));
195         testCases.add(new DoubleToFractionTestCase(6d / 11d, 6, 11));
196         testCases.add(new DoubleToFractionTestCase(7d / 11d, 7, 11));
197         testCases.add(new DoubleToFractionTestCase(8d / 11d, 8, 11));
198         testCases.add(new DoubleToFractionTestCase(9d / 11d, 9, 11));
199         testCases.add(new DoubleToFractionTestCase(10d / 11d, 10, 11));
200 
201         testCases.add(new DoubleToFractionTestCase(-1d / 2d, -1, 2));
202         testCases.add(new DoubleToFractionTestCase(-1d / 3d, -1, 3));
203 
204         testCases.add(new DoubleToFractionTestCase(0.00000000000001, 0, 1));
205         testCases.add(new DoubleToFractionTestCase(0.40000000000001, 2, 5));
206         testCases.add(new DoubleToFractionTestCase(15.0000000000001, 15, 1));
207         testCases.add(new DoubleToFractionTestCase(15.0, 15, 1));
208         testCases.add(new DoubleToFractionTestCase(0.0, 0, 1));
209         testCases.add(new DoubleToFractionTestCase(-0.0, 0, 1));
210 
211         return testCases;
212     }
213 
214     /**
215      * Defines test cases as described in
216      * {@link #doubleMaxDenomConstructorTestCases()} and collects them into a {@code List}.
217      * @return a list of test cases as described above
218      */
219     private static List<DoubleToFractionTestCase> collectDoubleMaxDenomConstructorTestCases() {
220         final List<DoubleToFractionTestCase> testCases = new ArrayList<>();
221         testCases.add(new DoubleToFractionTestCase(0.4,   9, 2, 5));
222         testCases.add(new DoubleToFractionTestCase(0.4,  99, 2, 5));
223         testCases.add(new DoubleToFractionTestCase(0.4, 999, 2, 5));
224         testCases.add(new DoubleToFractionTestCase(-0.4,   9, -2, 5));
225         testCases.add(new DoubleToFractionTestCase(-0.4,  99, -2, 5));
226         testCases.add(new DoubleToFractionTestCase(-0.4, 999, -2, 5));
227 
228         testCases.add(new DoubleToFractionTestCase(0.6152,    9, 3, 5));
229         testCases.add(new DoubleToFractionTestCase(0.6152,   99, 8, 13));
230         testCases.add(new DoubleToFractionTestCase(0.6152,  999, 510, 829));
231         testCases.add(new DoubleToFractionTestCase(0.6152, 9999, 769, 1250));
232         testCases.add(new DoubleToFractionTestCase(-0.6152,    9, -3, 5));
233         testCases.add(new DoubleToFractionTestCase(-0.6152,   99, -8, 13));
234         testCases.add(new DoubleToFractionTestCase(-0.6152,  999, -510, 829));
235         testCases.add(new DoubleToFractionTestCase(-0.6152, 9999, -769, 1250));
236 
237         // Underflow
238         testCases.add(new DoubleToFractionTestCase(0x1.0p-40, Integer.MAX_VALUE, 0, 1));
239         testCases.add(new DoubleToFractionTestCase(-0x1.0p-40, Integer.MAX_VALUE, 0, 1));
240 
241         // Overflow
242         testCases.add(new DoubleToFractionTestCase(Math.nextUp((double) Integer.MAX_VALUE), Integer.MIN_VALUE, Integer.MAX_VALUE, 1));
243         testCases.add(new DoubleToFractionTestCase(-Math.nextUp((double) Integer.MAX_VALUE), Integer.MIN_VALUE, -Integer.MAX_VALUE, 1));
244         testCases.add(new DoubleToFractionTestCase(Math.nextUp((double) Integer.MAX_VALUE) / (1 << 15), Integer.MIN_VALUE, Integer.MAX_VALUE, 1 << 15));
245         testCases.add(new DoubleToFractionTestCase(-Math.nextUp((double) Integer.MAX_VALUE) / (1 << 15), Integer.MIN_VALUE, -Integer.MAX_VALUE, 1 << 15));
246         testCases.add(new DoubleToFractionTestCase(Math.nextUp(1.0), Integer.MIN_VALUE, 1, 1));
247         testCases.add(new DoubleToFractionTestCase(-Math.nextUp(1.0), Integer.MIN_VALUE, -1, 1));
248 
249         // MATH-996
250         testCases.add(new DoubleToFractionTestCase(0.5000000001, 10, 1, 2));
251         testCases.add(new DoubleToFractionTestCase(-0.5000000001, 10, -1, 2));
252 
253         // NUMBERS-147
254         testCases.add(new DoubleToFractionTestCase(Integer.MAX_VALUE * 1.0, 2, Integer.MAX_VALUE, 1));
255         testCases.add(new DoubleToFractionTestCase(Integer.MAX_VALUE * -1.0, 2, -Integer.MAX_VALUE, 1));
256         testCases.add(new DoubleToFractionTestCase(1.0 / Integer.MAX_VALUE, Integer.MAX_VALUE, 1, Integer.MAX_VALUE));
257         testCases.add(new DoubleToFractionTestCase(-1.0 / Integer.MAX_VALUE, Integer.MAX_VALUE, -1, Integer.MAX_VALUE));
258         testCases.add(new DoubleToFractionTestCase(Integer.MIN_VALUE * 1.0, 2, Integer.MIN_VALUE, 1));
259 
260         // Using 2^31:
261         // Representations in Fraction and BigFraction are different since BigFraction
262         // can use +2^31 but Fraction is limited to -2^31
263         // .from(Integer.MIN_VALUE * -1.0, 2)
264         // .from(Integer.MIN_VALUE / -3.0, Integer.MIN_VALUE)
265         // .from(1.0 / Integer.MIN_VALUE, Integer.MIN_VALUE)
266         // .from(-1.0 / Integer.MIN_VALUE, Integer.MIN_VALUE)
267 
268         return testCases;
269     }
270 
271     /**
272      * Defines test cases as described in {@link #absTestCases()} and
273      * collects them into a {@code List}.
274      * @return a list of test cases as described above
275      */
276     private static List<UnaryOperatorTestCase> collectAbsTestCases() {
277         final List<UnaryOperatorTestCase> testCases = new ArrayList<>();
278 
279         testCases.add(new UnaryOperatorTestCase(10, 21, 10, 21));
280         testCases.add(new UnaryOperatorTestCase(-11, 23, 11, 23));
281         testCases.add(new UnaryOperatorTestCase(13, -24, -13, -24));
282         testCases.add(new UnaryOperatorTestCase(0, 1, 0, 1));
283         testCases.add(new UnaryOperatorTestCase(0, -1, 0, 1));
284 
285         return testCases;
286     }
287 
288     /**
289      * Defines test cases as described in {@link #reciprocalTestCases()} and
290      * collects them into a {@code List}.
291      * @return a list of test cases as described above
292      */
293     private static List<UnaryOperatorTestCase> collectReciprocalTestCases() {
294         final List<UnaryOperatorTestCase> testCases = new ArrayList<>();
295 
296         testCases.add(new UnaryOperatorTestCase(50, 75, 3, 2));
297         testCases.add(new UnaryOperatorTestCase(4, 3, 3, 4));
298         testCases.add(new UnaryOperatorTestCase(-15, 47, 47, -15));
299         testCases.add(new UnaryOperatorTestCase(Integer.MAX_VALUE, 1, 1, Integer.MAX_VALUE));
300 
301         return testCases;
302     }
303 
304     /**
305      * Defines test cases as described in {@link #negateTestCases()} and
306      * collects them into a {@code List}.
307      * @return a list of test cases as described above
308      */
309     private static List<UnaryOperatorTestCase> collectNegateTestCases() {
310         final List<UnaryOperatorTestCase> testCases = new ArrayList<>();
311 
312         testCases.add(new UnaryOperatorTestCase(50, 75, -2, 3));
313         testCases.add(new UnaryOperatorTestCase(-50, 75, 2, 3));
314         testCases.add(new UnaryOperatorTestCase(Integer.MAX_VALUE - 1, Integer.MAX_VALUE, Integer.MIN_VALUE + 2, Integer.MAX_VALUE));
315         testCases.add(new UnaryOperatorTestCase(1, Integer.MIN_VALUE, -1, Integer.MIN_VALUE));
316         testCases.add(new UnaryOperatorTestCase(0, 1, 0, 1));
317         testCases.add(new UnaryOperatorTestCase(0, -1, 0, 1));
318 
319         // XXX Failed by "BigFraction" (whose implementation differs from "Fraction").
320         // These are tested explicitly in FractionTest.
321         // testCases.add(new UnaryOperatorTestCase(Integer.MIN_VALUE, Integer.MIN_VALUE, -1, 1));
322         // testCases.add(new UnaryOperatorTestCase(Integer.MIN_VALUE, 1, Integer.MIN_VALUE, -1));
323 
324         return testCases;
325     }
326 
327     /**
328      * Defines test cases as described in {@link #addFractionTestCases()} and
329      * collects them into a {@code List}.
330      * @return a list of test cases as described above
331      */
332     private static List<BinaryOperatorTestCase> collectAddFractionTestCases() {
333         final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
334 
335         testCases.add(new BinaryOperatorTestCase(1, 2, 1, 2, 1, 1));
336         testCases.add(new BinaryOperatorTestCase(1, 2, 2, 3, 7, 6));
337         testCases.add(new BinaryOperatorTestCase(2, 3, 1, 2, 7, 6));
338         testCases.add(new BinaryOperatorTestCase(2, 3, 2, 3, 4, 3));
339         testCases.add(new BinaryOperatorTestCase(2, 3, 0, 5, 2, 3));
340         testCases.add(new BinaryOperatorTestCase(2, 3, 0, -5, 2, 3));
341         testCases.add(new BinaryOperatorTestCase(0, 7, 2, 3, 2, 3));
342         testCases.add(new BinaryOperatorTestCase(0, -7, 2, 3, 2, 3));
343         testCases.add(new BinaryOperatorTestCase(2, 3, -2, 3, 0, 1));
344 
345         testCases.add(new BinaryOperatorTestCase(
346                 -1, 13 * 13 * 2 * 2,
347                 -2, 13 * 17 * 2,
348                 -17 - 2 * 13 * 2,
349                 13 * 13 * 17 * 2 * 2));
350 
351         // if this fraction is added naively, it will overflow the int range.
352         // check that it doesn't.
353         testCases.add(new BinaryOperatorTestCase(
354                 1, 32768 * 3,
355                 1, 59049,
356                 52451, 1934917632));
357 
358         testCases.add(new BinaryOperatorTestCase(
359                 Integer.MIN_VALUE, 3,
360                 1, 3,
361                 Integer.MIN_VALUE + 1, 3));
362 
363         testCases.add(new BinaryOperatorTestCase(
364                 Integer.MAX_VALUE - 1, 1,
365                 1, 1,
366                 Integer.MAX_VALUE, 1));
367 
368         //NUMBERS-129
369         testCases.add(new BinaryOperatorTestCase(
370                 362564597, 10,
371                 274164323, 6,
372                 1229257703, 15));
373 
374         return testCases;
375     }
376 
377     /**
378      * Defines test cases as described in {@link #addIntTestCases()} and
379      * collects them into a {@code List}.
380      * @return a list of test cases as described above
381      */
382     private static List<BinaryIntOperatorTestCase> collectAddIntTestCases() {
383         final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
384 
385         testCases.add(new BinaryIntOperatorTestCase(1, 3, 0, 1, 3));
386         testCases.add(new BinaryIntOperatorTestCase(-1, 3, 0, -1, 3));
387         testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, 4, 3));
388         testCases.add(new BinaryIntOperatorTestCase(1, 3, -1, -2, 3));
389         testCases.add(new BinaryIntOperatorTestCase(2, -1, 2, 0, 1));
390         testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE - 1, 1, 1, Integer.MAX_VALUE, 1));
391 
392         return testCases;
393     }
394 
395     /**
396      * Defines test cases as described in
397      * {@link #divideByFractionTestCases()} and collects them into a {@code List}.
398      * @return a list of test cases as described above
399      */
400     private static List<BinaryOperatorTestCase> collectDivideByFractionTestCases() {
401         final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
402 
403         testCases.add(new BinaryOperatorTestCase(1, 2, 1, 2, 1, 1));
404         testCases.add(new BinaryOperatorTestCase(1, 2, 2, 3, 3, 4));
405         testCases.add(new BinaryOperatorTestCase(2, 3, 1, 2, 4, 3));
406         testCases.add(new BinaryOperatorTestCase(2, 3, 2, 3, 1, 1));
407         testCases.add(new BinaryOperatorTestCase(0, 3, 2, 3, 0, 1));
408         // Return the original zero representation
409         testCases.add(new BinaryOperatorTestCase(0, -3, 2, 3, 0, 1));
410 
411         testCases.add(new BinaryOperatorTestCase(
412                 2, 7,
413                 1, 1,
414                 2, 7));
415         testCases.add(new BinaryOperatorTestCase(
416                 1, Integer.MAX_VALUE,
417                 1, Integer.MAX_VALUE,
418                 1, 1));
419         testCases.add(new BinaryOperatorTestCase(
420                 Integer.MIN_VALUE, Integer.MAX_VALUE,
421                 1, Integer.MAX_VALUE,
422                 Integer.MIN_VALUE, 1));
423 
424         return testCases;
425     }
426 
427     /**
428      * Defines test cases as described in
429      * {@link #divideByIntTestCases()} and collects them into a {@code List}.
430      * @return a list of test cases as described above
431      */
432     private static List<BinaryIntOperatorTestCase> collectDivideByIntTestCases() {
433         final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
434 
435         testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, 1, 3));
436         testCases.add(new BinaryIntOperatorTestCase(0, 5, 11, 0, 1));
437         testCases.add(new BinaryIntOperatorTestCase(6, 35, 15, 2, 175));
438 
439         // This captures an implementation detail
440         testCases.add(new BinaryIntOperatorTestCase(1, 3, -1, 1, -3));
441 
442         return testCases;
443     }
444 
445     /**
446      * Defines test cases as described in
447      * {@link #multiplyByFractionTestCases()} and collects them into a {@code List}.
448      * @return a list of test cases as described above
449      */
450     private static List<BinaryOperatorTestCase> collectMultiplyByFractionTestCases() {
451         final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
452 
453         testCases.add(new BinaryOperatorTestCase(1, 2, 1, 2, 1, 4));
454         testCases.add(new BinaryOperatorTestCase(1, 2, 2, 3, 1, 3));
455         testCases.add(new BinaryOperatorTestCase(2, 3, 1, 2, 1, 3));
456         testCases.add(new BinaryOperatorTestCase(2, 3, 2, 3, 4, 9));
457         testCases.add(new BinaryOperatorTestCase(0, 3, 2, 3, 0, 1));
458         testCases.add(new BinaryOperatorTestCase(0, -3, 2, 3, 0, 1));
459         testCases.add(new BinaryOperatorTestCase(2, 3, 0, 3, 0, 1));
460         testCases.add(new BinaryOperatorTestCase(2, 3, 0, -3, 0, 1));
461 
462         testCases.add(new BinaryOperatorTestCase(
463                 Integer.MAX_VALUE, 1,
464                 Integer.MIN_VALUE, Integer.MAX_VALUE,
465                 Integer.MIN_VALUE, 1));
466 
467         return testCases;
468     }
469 
470     /**
471      * Defines test cases as described in
472      * {@link #multiplyByIntTestCases()} and collects them into a {@code List}.
473      * @return a list of test cases as described above
474      */
475     private static List<BinaryIntOperatorTestCase> collectMultiplyByIntTestCases() {
476         final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
477 
478         testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, 1, 3));
479         testCases.add(new BinaryIntOperatorTestCase(6, 35, 15, 18, 7));
480         testCases.add(new BinaryIntOperatorTestCase(Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, 1));
481         // Test zero with multiply by integer
482         testCases.add(new BinaryIntOperatorTestCase(0, 1, 42, 0, 1));
483         testCases.add(new BinaryIntOperatorTestCase(1, 1, 0, 0, 1));
484 
485         // This captures an implementation detail
486         testCases.add(new BinaryIntOperatorTestCase(1, 3, -1, -1, 3));
487 
488         return testCases;
489     }
490 
491     /**
492      * Defines test cases as described in
493      * {@link #subtractFractionTestCases()} and collects them into a {@code List}.
494      * @return a list of test cases as described above
495      */
496     private static List<BinaryOperatorTestCase> collectSubtractFractionTestCases() {
497         final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
498 
499         testCases.add(new BinaryOperatorTestCase(1, 2, 1, 2, 0, 1));
500         testCases.add(new BinaryOperatorTestCase(1, 2, 2, 3, -1, 6));
501         testCases.add(new BinaryOperatorTestCase(2, 3, 1, 2, 1, 6));
502         testCases.add(new BinaryOperatorTestCase(2, 3, 2, 3, 0, 1));
503         testCases.add(new BinaryOperatorTestCase(0, 3, 1, 5, -1, 5));
504         testCases.add(new BinaryOperatorTestCase(0, -3, 1, 5, -1, 5));
505         testCases.add(new BinaryOperatorTestCase(2, 3, 0, 5, 2, 3));
506         testCases.add(new BinaryOperatorTestCase(2, 3, 0, -5, 2, 3));
507 
508         // if this fraction is subtracted naively, it will overflow the int range.
509         // check that it doesn't.
510         testCases.add(new BinaryOperatorTestCase(
511                 1, 32768 * 3,
512                 1, 59049,
513                 -13085, 1934917632));
514 
515         testCases.add(new BinaryOperatorTestCase(
516                 Integer.MIN_VALUE, 3,
517                 -1, 3,
518                 Integer.MIN_VALUE + 1, 3
519         ));
520 
521         testCases.add(new BinaryOperatorTestCase(
522                 Integer.MAX_VALUE, 1,
523                 1, 1,
524                 Integer.MAX_VALUE - 1, 1
525         ));
526 
527         return testCases;
528     }
529 
530     /**
531      * Defines test cases as described in
532      * {@link #subtractIntTestCases()} and collects them into a {@code List}.
533      * @return a list of test cases as described above
534      */
535     private static List<BinaryIntOperatorTestCase> collectSubtractIntTestCases() {
536         final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
537 
538         testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, -2, 3));
539         testCases.add(new BinaryIntOperatorTestCase(0, 1, 3, -3, 1));
540         testCases.add(new BinaryIntOperatorTestCase(2, 3, 3, -7, 3));
541         testCases.add(new BinaryIntOperatorTestCase(2, 3, 0, 2, 3));
542         testCases.add(new BinaryIntOperatorTestCase(2, -1, -2, 0, 1));
543 
544         return testCases;
545     }
546 
547     /**
548      * Defines test cases as described in
549      * {@link #powTestCases()} and collects them into a {@code List}.
550      * @return a list of test cases as described above
551      */
552     private static List<BinaryIntOperatorTestCase> collectPowTestCases() {
553         final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
554 
555         testCases.add(new BinaryIntOperatorTestCase(3, 7, 0, 1, 1));
556         testCases.add(new BinaryIntOperatorTestCase(3, 7, 1, 3, 7));
557         testCases.add(new BinaryIntOperatorTestCase(3, 7, -1, 7, 3));
558         testCases.add(new BinaryIntOperatorTestCase(3, 7, 2, 9, 49));
559         testCases.add(new BinaryIntOperatorTestCase(3, 7, -2, 49, 9));
560 
561         testCases.add(new BinaryIntOperatorTestCase(3, -7, 0, 1, 1));
562         testCases.add(new BinaryIntOperatorTestCase(3, -7, 1, 3, -7));
563         testCases.add(new BinaryIntOperatorTestCase(3, -7, -1, -7, 3));
564         testCases.add(new BinaryIntOperatorTestCase(3, -7, 2, 9, 49));
565         testCases.add(new BinaryIntOperatorTestCase(3, -7, -2, 49, 9));
566 
567         testCases.add(new BinaryIntOperatorTestCase(2, 3, 13, 8192, 1594323));
568         testCases.add(new BinaryIntOperatorTestCase(2, 3, -13, 1594323, 8192));
569 
570         testCases.add(new BinaryIntOperatorTestCase(0, 1, Integer.MAX_VALUE, 0, 1));
571         testCases.add(new BinaryIntOperatorTestCase(0, -1, Integer.MAX_VALUE, 0, 1));
572 
573         testCases.add(new BinaryIntOperatorTestCase(1, 1, Integer.MIN_VALUE, 1, 1));
574         testCases.add(new BinaryIntOperatorTestCase(1, -1, Integer.MIN_VALUE, 1, 1));
575         testCases.add(new BinaryIntOperatorTestCase(-1, 1, Integer.MIN_VALUE, 1, 1));
576         testCases.add(new BinaryIntOperatorTestCase(-1, -1, Integer.MIN_VALUE, 1, 1));
577         return testCases;
578     }
579 
580     /**
581      * Provides a list of test cases where a fraction should be created from
582      * a specified numerator and denominator, both in the {@code int} range,
583      * and the expected numerator and denominator of the created fraction are
584      * also in the {@code int} range.
585      *
586      * @return a list of test cases as described above
587      */
588     static List<UnaryOperatorTestCase> numDenConstructorTestCases() {
589         return Collections.unmodifiableList(numDenConstructorTestCasesList);
590     }
591 
592     /**
593      * Provides a list of test cases where a {@code double} value should be
594      * converted to a fraction with a certain amount of absolute error
595      * allowed, and the expected numerator and denominator of the resulting
596      * fraction are in the {@code int} range.
597      *
598      * <p>The maximum denominator in the test cases will be zero and should be ignored.
599      *
600      * @return a list of test cases as described above
601      */
602     static List<DoubleToFractionTestCase> doubleConstructorTestCases() {
603         return Collections.unmodifiableList(doubleConstructorTestCasesList);
604     }
605 
606     /**
607      * Provides a list of test cases where a {@code double} value should be
608      * converted to a fraction with a specified maximum denominator, and the
609      * expected numerator and denominator of the resulting fraction are in the
610      * {@code int} range.
611      *
612      * @return a list of test cases as described above
613      */
614     static List<DoubleToFractionTestCase> doubleMaxDenomConstructorTestCases() {
615         return Collections.unmodifiableList(doubleMaxDenomConstructorTestCasesList);
616     }
617 
618     /**
619      * Provides a list of test cases where the absolute value of a fraction
620      * created from a specified numerator and denominator, both in the {@code
621      * int} range, should be calculated, and the expected numerator and
622      * denominator of the resulting fraction are also in the {@code int} range.
623      * @return a list of test cases as described above
624      */
625     static List<UnaryOperatorTestCase> absTestCases() {
626         return Collections.unmodifiableList(absTestCasesList);
627     }
628 
629     /**
630      * Provides a list of test cases where the multiplicative inverse of a
631      * fraction created from a specified numerator and denominator, both in
632      * the {@code int} range, should be calculated, and the expected
633      * numerator and denominator of the resulting fraction are also in the
634      * {@code int} range.
635      *
636      * @return a list of test cases as described above
637      */
638     static List<UnaryOperatorTestCase> reciprocalTestCases() {
639         return Collections.unmodifiableList(reciprocalTestCasesList);
640     }
641 
642     /**
643      * Provides a list of test cases where the additive inverse of a fraction
644      * created from a specified numerator and denominator, both in the {@code
645      * int} range, should be calculated, and the expected numerator and
646      * denominator of the resulting fraction are also in the {@code int} range.
647      *
648      * @return a list of test cases as described above
649      */
650     static List<UnaryOperatorTestCase> negateTestCases() {
651         return Collections.unmodifiableList(negateTestCasesList);
652     }
653 
654     /**
655      * Provides a list of test cases where two fractions, each created from a
656      * specified numerator and denominator in the {@code int} range, should
657      * be added, and the expected numerator and denominator of the resulting
658      * fraction are also in the {@code int} range.
659      *
660      * @return a list of test cases as described above
661      */
662     static List<BinaryOperatorTestCase> addFractionTestCases() {
663         return Collections.unmodifiableList(addFractionTestCasesList);
664     }
665 
666     /**
667      * Provides a list of test cases where a fraction, created from a
668      * specified numerator and denominator in the {@code int} range, should
669      * be added to a specified value in the {@code int} range,
670      * and the expected numerator and denominator of the resulting fraction
671      * are in the {@code int} range as well.
672      *
673      * @return a list of test cases as described above
674      */
675     static List<BinaryIntOperatorTestCase> addIntTestCases() {
676         return Collections.unmodifiableList(addIntTestCasesList);
677     }
678 
679     /**
680      * Provides a list of test cases where a fraction, created from a
681      * specified numerator and denominator in the {@code int} range, should
682      * be divided by another fraction, also created from a specified
683      * numerator and denominator in the {@code int} range, and the expected
684      * numerator and denominator of the resulting fraction are in the {@code
685      * int} range as well.
686      *
687      * <p>The first operand in each test case is the dividend and the second
688      * operand is the divisor.</p>
689      *
690      * @return a list of test cases as described above
691      */
692     static List<BinaryOperatorTestCase> divideByFractionTestCases() {
693         return Collections.unmodifiableList(divideByFractionTestCasesList);
694     }
695 
696     /**
697      * Provides a list of test cases where a fraction, created from a
698      * specified numerator and denominator in the {@code int} range, should
699      * be divided by a specified value in the {@code int} range,
700      * and the expected numerator and denominator of the resulting fraction
701      * are in the {@code int} range as well.
702      *
703      * <p>The first operand in each test case is the dividend and the second
704      * operand is the divisor.</p>
705      *
706      * @return a list of test cases as described above
707      */
708     static List<BinaryIntOperatorTestCase> divideByIntTestCases() {
709         return Collections.unmodifiableList(divideByIntTestCasesList);
710     }
711 
712     /**
713      * Provides a list of test cases where a fraction, created from a
714      * specified numerator and denominator in the {@code int} range, should
715      * be multiplied by another fraction, also created from a specified
716      * numerator and denominator in the {@code int} range, and the expected
717      * numerator and denominator of the resulting fraction are in the {@code
718      * int} range as well.
719      *
720      * @return a list of test cases as described above
721      */
722     static List<BinaryOperatorTestCase> multiplyByFractionTestCases() {
723         return Collections.unmodifiableList(multiplyByFractionTestCasesList);
724     }
725 
726     /**
727      * Provides a list of test cases where a fraction, created from a
728      * specified numerator and denominator in the {@code int} range, should
729      * be multiplied by a specified value in the {@code int} range,
730      * and the expected numerator and denominator of the resulting fraction
731      * are in the {@code int} range as well.
732      *
733      * @return a list of test cases as described above
734      */
735     static List<BinaryIntOperatorTestCase> multiplyByIntTestCases() {
736         return Collections.unmodifiableList(multiplyByIntTestCasesList);
737     }
738 
739     /**
740      * Provides a list of test cases where a fraction, created from a
741      * specified numerator and denominator in the {@code int} range, should
742      * be subtracted from another fraction, also created from a specified
743      * numerator and denominator in the {@code int} range, and the expected
744      * numerator and denominator of the resulting fraction are in the {@code
745      * int} range as well.
746      *
747      * <p>The first operand in each test case is the minuend and the second
748      * operand is the subtrahend.</p>
749      *
750      * @return a list of test cases as described above
751      */
752     static List<BinaryOperatorTestCase> subtractFractionTestCases() {
753         return Collections.unmodifiableList(subtractFractionTestCasesList);
754     }
755 
756     /**
757      * Provides a list of test cases where a fraction, created from a
758      * specified numerator and denominator in the {@code int} range, should
759      * have a specified value in the {@code int} range subtracted,
760      * and the expected numerator and denominator of the resulting fraction
761      * are in the {@code int} range as well.
762      *
763      * <p>The first operand in each test case is the minuend and the second
764      * operand is the subtrahend.</p>
765      *
766      * @return a list of test cases as described above
767      */
768     static List<BinaryIntOperatorTestCase> subtractIntTestCases() {
769         return Collections.unmodifiableList(subtractIntTestCasesList);
770     }
771 
772     /**
773      * Provides a list of test cases where a fraction, created from a
774      * specified numerator and denominator in the {@code int} range, should
775      * be raised to a specified power specified in the {@code int} range,
776      * and the expected numerator and denominator of the resulting fraction
777      * are in the {@code int} range as well.
778      *
779      * @return a list of test cases as described above
780      */
781     static List<BinaryIntOperatorTestCase> powTestCases() {
782         return Collections.unmodifiableList(powTestCasesList);
783     }
784 
785     // CHECKSTYLE: stop VisibilityModifier
786 
787     /**
788      * Represents a test case where a unary operation should be performed on
789      * a specified combination of numerator and denominator, both in the
790      * {@code int} range, and the numerator and denominator of the expected
791      * result are also in the {@code int} range.
792      */
793     static class UnaryOperatorTestCase {
794         final int operandNumerator;
795         final int operandDenominator;
796         final int expectedNumerator;
797         final int expectedDenominator;
798 
799         UnaryOperatorTestCase(
800                 int operandNumerator,
801                 int operandDenominator,
802                 int expectedNumerator,
803                 int expectedDenominator) {
804             this.operandNumerator = operandNumerator;
805             this.operandDenominator = operandDenominator;
806             this.expectedNumerator = expectedNumerator;
807             this.expectedDenominator = expectedDenominator;
808         }
809     }
810 
811     /**
812      * Represents a test case where a binary operation should be performed on
813      * two specified combinations of numerator and denominator, with the
814      * numerator and denominator of each combination in the {@code int}
815      * range, and the numerator and denominator of the expected result are
816      * also in the {@code int} range.
817      */
818     static class BinaryOperatorTestCase {
819         final int firstOperandNumerator;
820         final int firstOperandDenominator;
821         final int secondOperandNumerator;
822         final int secondOperandDenominator;
823         final int expectedNumerator;
824         final int expectedDenominator;
825 
826         BinaryOperatorTestCase(
827                 int firstOperandNumerator,
828                 int firstOperandDenominator,
829                 int secondOperandNumerator,
830                 int secondOperandDenominator,
831                 int expectedNumerator,
832                 int expectedDenominator) {
833             this.firstOperandNumerator = firstOperandNumerator;
834             this.firstOperandDenominator = firstOperandDenominator;
835             this.secondOperandNumerator = secondOperandNumerator;
836             this.secondOperandDenominator = secondOperandDenominator;
837             this.expectedNumerator = expectedNumerator;
838             this.expectedDenominator = expectedDenominator;
839         }
840     }
841 
842     /**
843      * Represents a test case where a binary operation should be performed on
844      * a specified combination of numerator and denominator and a integer argument,
845      * with the numerator and denominator in the {@code int}
846      * range, and the numerator and denominator of the expected result are
847      * also in the {@code int} range.
848      */
849     static class BinaryIntOperatorTestCase {
850         final int firstOperandNumerator;
851         final int firstOperandDenominator;
852         final int secondOperand;
853         final int expectedNumerator;
854         final int expectedDenominator;
855 
856         BinaryIntOperatorTestCase(
857                 int firstOperandNumerator,
858                 int firstOperandDenominator,
859                 int secondOperand,
860                 int expectedNumerator,
861                 int expectedDenominator) {
862             this.firstOperandNumerator = firstOperandNumerator;
863             this.firstOperandDenominator = firstOperandDenominator;
864             this.secondOperand = secondOperand;
865             this.expectedNumerator = expectedNumerator;
866             this.expectedDenominator = expectedDenominator;
867         }
868     }
869 
870     /**
871      * Represents a test case where an operation that yields a fraction
872      * should be performed on a {@code double} value and the numerator and
873      * denominator of the expected result
874      * are in the {@code int} range.
875      *
876      * <p>Optionally captures a maximum denominator. This will be zero if
877      * not required in the test case.
878      */
879     static class DoubleToFractionTestCase {
880         final double operand;
881         final int maxDenominator;
882         final int expectedNumerator;
883         final int expectedDenominator;
884 
885         DoubleToFractionTestCase(
886                 double operand,
887                 int maxDenominator,
888                 int expectedNumerator,
889                 int expectedDenominator) {
890             this.operand = operand;
891             this.maxDenominator = maxDenominator;
892             this.expectedNumerator = expectedNumerator;
893             this.expectedDenominator = expectedDenominator;
894         }
895 
896         DoubleToFractionTestCase(
897                 double operand,
898                 int expectedNumerator,
899                 int expectedDenominator) {
900             this(operand, 0, expectedNumerator, expectedDenominator);
901         }
902     }
903 }