001package hw3.test;
002
003import hw3.*;
004
005import org.junit.Test;
006import org.junit.BeforeClass;
007import static org.junit.Assert.*;
008import static org.hamcrest.CoreMatchers.*;
009
010/**
011 * This class contains a <em>small</em> set of test cases that can be used to
012 * test the implementation of the RatNum class. For a more complete test, see
013 * <tt>RatNumTest</tt>. This class, <tt>RatNumSmallTest</tt>, deliberately
014 * omits some of the tests from <tt>RatNumTest</tt>, to permit comparing the
015 * effects of the two test suites.
016 */
017public final class RatNumSmallTest {
018
019    // Naming convention used throughout class: spell out number in
020    // variable as its constructive form. Unary minus is notated with
021    // the prefix "neg", and the solidus ("/") is notated with an 'I'
022    // character. Thus, "1 + 2/3" becomes "one_plus_two_I_three".
023
024    // some simple base RatNums
025    private RatNum zero = new RatNum(0);
026    private RatNum one = new RatNum(1);
027    private RatNum negOne = new RatNum(-1);
028    private RatNum two = new RatNum(2);
029    private RatNum three = new RatNum(3);
030    private RatNum one_I_two = new RatNum(1, 2);
031    private RatNum one_I_three = new RatNum(1, 3);
032    private RatNum one_I_four = new RatNum(1, 4);
033    private RatNum two_I_three = new RatNum(2, 3);
034    private RatNum three_I_four = new RatNum(3, 4);
035    private RatNum negOne_I_two = new RatNum(-1, 2);
036
037    // improper fraction
038    private RatNum three_I_two = new RatNum(3, 2);
039
040    // NaNs
041    private RatNum one_I_zero = new RatNum(1, 0);
042    private RatNum negOne_I_zero = new RatNum(-1, 0);
043    private RatNum hundred_I_zero = new RatNum(100, 0);
044
045    /**
046     * ratnums: Set of varied ratnums (includes NaNs) set is { 0, 1, -1, 2, 1/2,
047     * 3/2, 1/0, -1/0, 100/0 }
048     */
049    private RatNum[] ratNums = new RatNum[] { zero, one, negOne, two,
050            one_I_two, negOne_I_two, three_I_two,
051            /* NaNs */one_I_zero, negOne_I_zero, hundred_I_zero };
052
053    /**
054     * ratnans: Set of varied NaNs set is { 1/0, -1/0, 100/0 }
055     */
056    private RatNum[] ratNaNs = new RatNum[] { one_I_zero, negOne_I_zero,
057            hundred_I_zero };
058
059    /**
060     * ratNonNaNs: Set of varied non-NaN ratNums set is ratNums - ratNaNs
061     */
062    private RatNum[] ratNonNaNs = new RatNum[] { zero, one, negOne, two,
063            one_I_two, three_I_two };
064
065    /**
066     * Asserts that RatNum.toString() is equal to rep. This method depends on the
067     * implementation of RatNum's "toString" and "equals" methods. Therefore,
068     * one should verify (test) those methods before using this method is in
069     * tests.
070     */
071    private void eq(RatNum ratNum, String rep) {
072        assertEquals(rep, ratNum.toString());
073    }
074
075    // The actual test cases are below.
076    //
077    // The order of the test cases is important for producing useful
078    // output. If a test uses a method of RatNum, it should test that
079    // method before hand. For example, suppose one of the test cases
080    // for "negate" is:
081    //
082    // "(new RatNum(1)).negate().equals(new RatNum(-1))"
083    //
084    // In this case, the test case relies on RatNum's "equals" method
085    // in addition to "negate"; therefore, one should test "equals"
086    // before "negate". Otherwise, it will be unclear if failing the
087    // "negate" test is due "negate" having a bug or "equals" having a
088    // bug. (Furthermore, the test depends on RatNum's constructor,
089    // so it should also be tested beforehand.)
090    //
091    // In general, it is best to have as few dependences in your test
092    // cases as possible. Doing so, will reduce the number of methods
093    // that could cause a test case to fail, making it easier to find
094    // the faulty method. In practice, one will usually need to
095    // depend on a few core methods such as the constructors and
096    // "equals" methods. Also, some of the test cases below depend on
097    // the "toString" method because it made the cases easier to write.
098    //
099    // As a secondary concern to above, if one has access to the
100    // source code of a class (as under glass box testing) one should
101    // order tests such that a method is tested after all the methods
102    // it depends on are tested. For example, in RatNum, the "sub"
103    // method calls the "negate" method; therefore, one should test
104    // "negate" before "sub". Following this methodology will make it
105    // more clear that one should fix bugs in "negate" before looking
106    // at the results of "sub" test because, "sub" could be correctly
107    // written and the "sub" test case fails only be "negate" is
108    // broken.
109    //
110    // If one does not have access to the source code (as is the case
111    // of RatTermTest and RatPolyTest, because you are proving the
112    // implementations), one can still take an educated guess as to
113    // which methods depend on other methods, but don't worry about
114    // getting it perfect.
115
116    // First, we test the constructors in isolation of (without
117    // depending on) all other RatNum methods.
118    //
119    // Unfortunately, without using any of RatNum's methods, all we
120    // can do is call the constructors and ensure that "checkRep"
121    // passes. While this is useful, it does not catch many types of
122    // errors. For example, the constructor could always return a
123    // RatNum, r, where r.numer = 1 and r.denom = 1. Being a valid
124    // RatNum, r would pass "checkRep" but would be the wrong RatNum
125    // in most cases.
126    //
127    // Given that we are unable to fully test the constructors, when
128    // any other test case fails, it could be due to an error in the
129    // constructor instead of an error in method the test case is
130    // testing.
131    //
132    // If RatNum had public fields, this problem would not exist,
133    // because we could check if the fields were set to the correct
134    // values. This problem is really a case of a more general
135    // problem of being unable to test private fields and methods of
136    // classes. For example, we are also unable to test the gcd
137    // method because it is private. Solutions to this general
138    // problem include:
139    //
140    // (1) Make the private fields and methods public. (For example,
141    // make numer, denom, and gcd public.) This in not done in
142    // general because private fields have many benefits as will
143    // be discussed in class.
144    //
145    // (2) Move the test suite code into RatNum and, thus, it would
146    // have access to private memebers. (Maybe as a static inner
147    // class [Don't worry if you don't know what this means yet.])
148    // This is not done in general because it clutters the class
149    // being tested, making it harder to understand.
150    //
151    // In practice, while testing, you may find it necessary to do (1)
152    // or (2) temporarily with a test case that accesses private
153    // fields or methods to track down a bug. But after finding the
154    // bug, remember to revert your code back. Also for future
155    // problem sets where you will be writing your own test suites,
156    // make sure that your test suite runs correctly without (1) or
157    // (2) being true.
158
159    // (Note, all of these objects were already constructed above as
160    // fields of this class (RatNumTest); thus, one could argue that
161    // this test case is redundant. We included this test case anyhow
162    // to give you an example of such a test case and because the
163    // implementation of this class could change eliminating the
164    // fields above.)
165    @Test
166    public void testOneArgConstructor() {
167        new RatNum(0);
168        new RatNum(1);
169        new RatNum(-1);
170        new RatNum(2);
171        new RatNum(3);
172    }
173
174    @Test
175    public void testTwoArgConstructor() {
176        new RatNum(1, 2);
177        new RatNum(1, 3);
178        new RatNum(1, 4);
179        new RatNum(2, 3);
180        new RatNum(3, 4);
181
182        new RatNum(-1, 2);
183
184        // improper fraction
185        new RatNum(3, 2);
186
187        // NaNs
188        new RatNum(1, 0);
189        new RatNum(-1, 0);
190        new RatNum(100, 0);
191    }
192
193    // Next, we test isNaN because it can be tested in isolation from
194    // everything except the constructors. (All instance method tests
195    // will depend on a constructor.)
196    @Test
197    public void testIsNaN() {
198        for (int i = 0; i < ratNaNs.length; i++) {
199            assertTrue(ratNaNs[i].isNaN());
200        }
201        for (int i = 0; i < ratNonNaNs.length; i++) {
202            assertFalse(ratNonNaNs[i].isNaN());
203        }
204    }
205
206    // Next, we test isPos and isNeg because we can easily test these
207    // methods without depending on any other methods (except the
208    // constructors).
209    private void assertPos(RatNum n) {
210        assertTrue(n.isPositive());
211        assertFalse(n.isNegative());
212    }
213
214    private void assertNeg(RatNum n) {
215        assertTrue(n.isNegative());
216        assertFalse(n.isPositive());
217    }
218
219    @Test
220    public void testIsPosAndIsNeg() {
221        assertFalse(zero.isPositive());
222        assertFalse(zero.isNegative());
223
224        assertPos(one);
225        assertNeg(negOne);
226        assertPos(two);
227        assertPos(three);
228
229        assertPos(one_I_two);
230        assertPos(one_I_three);
231        assertPos(one_I_four);
232        assertPos(two_I_three);
233        assertPos(three_I_four);
234
235        assertNeg(negOne_I_two);
236
237        assertPos(three_I_two);
238
239        assertPos(one_I_zero);
240        assertPos(negOne_I_zero); // non-intuitive; see spec
241        assertPos(hundred_I_zero);
242    }
243
244    // Next, we test doubleValue because the test does not require any
245    // other RatNum methods (other than constructors).
246
247    // asserts that two double's are within .0000001 of one another.
248    // It is often impossible to assert that doubles are exactly equal
249    // because of the idiosyncrasies of Java's floating point math.
250    private void approxEq(double expected, double actual) {
251        assertEquals(expected, actual, .0000001);
252    }
253
254    @Test
255    public void testApprox() {
256        approxEq(0.0, zero.doubleValue());
257        approxEq(1.0, one.doubleValue());
258        approxEq(-1.0, negOne.doubleValue());
259        approxEq(2.0, two.doubleValue());
260        approxEq(0.5, one_I_two.doubleValue());
261        approxEq(2. / 3., two_I_three.doubleValue());
262        approxEq(0.75, three_I_four.doubleValue());
263
264        // To understand the use of "new Double(Double.NaN)" instead of
265        // "Double.NaN", see the Javadoc for Double.equals().
266        assertEquals(new Double(Double.NaN),
267                     new Double(one_I_zero.doubleValue()));
268
269        // use left-shift operator "<<" to create integer for 2^30
270        RatNum one_I_twoToThirty = new RatNum(1, (1 << 30));
271        double quiteSmall = 1. / Math.pow(2, 30);
272        approxEq(quiteSmall, one_I_twoToThirty.doubleValue());
273    }
274
275    // Next, we test the equals method because that can be tested in
276    // isolation from everything except the constructor and maybe
277    // isNaN, which we just tested.
278    // Additionally, this method will be very useful for testing other
279    // methods.
280
281    /**
282     * This test check is equals is reflexive. In other words that x.equals(x)
283     * is always true.
284     */
285    @Test
286    public void testEqualsReflexive() {
287        for (int i = 0; i < ratNums.length; i++) {
288            assertEquals(ratNums[i], ratNums[i]);
289        }
290    }
291
292    @Test
293    public void testEquals() {
294
295        // Some simple cases.
296        assertEquals(one, one);
297        assertEquals(one.add(one), two);
298        // including negitives:
299        assertEquals(negOne, negOne);
300
301        // Some simple cases where the objects are different but
302        // represent the same rational number. That is, x != y but
303        // x.equals(y).
304        assertEquals(new RatNum(1, 1), new RatNum(1, 1));
305        assertEquals(new RatNum(1, 2), new RatNum(1, 2));
306
307        // Check that equals works on fractions that were not
308        // constructed in reduced form.
309        assertEquals(one, new RatNum(2, 2));
310        assertEquals(new RatNum(2, 2), one);
311        // including negitives:
312        assertEquals(negOne, new RatNum(-9, 9));
313        assertEquals(new RatNum(-9, 9), negOne);
314        // including double negitives:
315        assertEquals(one_I_two, new RatNum(-13, -26));
316        assertEquals(new RatNum(-13, -26), one_I_two);
317
318        // Check that all NaN's are equals to one another.
319        assertEquals(one_I_zero, one_I_zero);
320        assertEquals(one_I_zero, negOne_I_zero);
321        assertEquals(one_I_zero, hundred_I_zero);
322
323        // Some simple cases checking for false positives.
324        assertThat(one, not(zero));
325        assertThat(zero, not(one));
326        assertThat(one, not(two));
327        assertThat(two, not(one));
328
329        // Check that equals does not neglect sign.
330        assertThat(one, not(negOne));
331        assertThat(negOne, not(one));
332
333        // Check that equals does not return false positives on
334        // fractions.
335        assertThat(one, not(one_I_two));
336        assertThat(one_I_two, not(one));
337        assertThat(one, not(three_I_two));
338        assertThat(three_I_two, not(one));
339    }
340
341    // Now that we have verified equals, we will use it in the
342    // rest or our tests.
343
344    // Next, we test the toString and valueOf methods because we can test
345    // them isolation of everything except the constructor and equals,
346    // and they will be useful methods to aid with testing other
347    // methods. (In some cases, it is easier to use valueOf("1/2") than
348    // new RatNum(1, 2) as you will see below.)
349
350    // Note that "eq" calls "toString" on its first argument.
351    @Test
352    public void testToStringSimple() {
353        eq(zero, "0");
354
355        eq(one, "1");
356
357        RatNum four = new RatNum(4);
358        eq(four, "4");
359
360        eq(negOne, "-1");
361
362        RatNum negFive = new RatNum(-5);
363        eq(negFive, "-5");
364
365        RatNum negZero = new RatNum(-0);
366        eq(negZero, "0");
367    }
368
369    @Test
370    public void testToStringFractions() {
371        RatNum one_I_two = new RatNum(1, 2);
372        eq(one_I_two, "1/2");
373
374        RatNum three_I_two = new RatNum(3, 2);
375        eq(three_I_two, "3/2");
376
377        RatNum negOne_I_thirteen = new RatNum(-1, 13);
378        eq(negOne_I_thirteen, "-1/13");
379
380        RatNum fiftyThree_I_seven = new RatNum(53, 7);
381        eq(fiftyThree_I_seven, "53/7");
382    }
383
384    @Test
385    public void testToStringNaN() {
386        RatNum one_I_zero = new RatNum(1, 0);
387        eq(one_I_zero, "NaN");
388
389        RatNum two_I_zero = new RatNum(2, 0);
390        eq(two_I_zero, "NaN");
391
392        RatNum negOne_I_zero = new RatNum(-1, 0);
393        eq(negOne_I_zero, "NaN");
394
395        RatNum zero_I_zero = new RatNum(0, 0);
396        eq(zero_I_zero, "NaN");
397
398        RatNum negHundred_I_zero = new RatNum(-100, 0);
399        eq(negHundred_I_zero, "NaN");
400
401        RatNum two_I_one = new RatNum(2, 1);
402        eq(two_I_one, "2");
403
404        RatNum zero_I_one = new RatNum(0, 1);
405        eq(zero_I_one, "0");
406
407        RatNum negOne_I_negTwo = new RatNum(-1, -2);
408        eq(negOne_I_negTwo, "1/2");
409
410        RatNum two_I_four = new RatNum(2, 4);
411        eq(two_I_four, "1/2");
412
413        RatNum six_I_four = new RatNum(6, 4);
414        eq(six_I_four, "3/2");
415
416        RatNum twentySeven_I_thirteen = new RatNum(27, 13);
417        eq(twentySeven_I_thirteen, "27/13");
418
419        RatNum negHundred_I_negHundred = new RatNum(-100, -100);
420        eq(negHundred_I_negHundred, "1");
421    }
422
423    // helper function, "decode-and-check"
424    private void decChk(String s, RatNum expected) {
425        RatNum.valueOf(s).equals(expected);
426    }
427
428    // Note that decChk calls valueOf.
429    @Test
430    public void testValueOf() {
431        decChk("0", zero);
432
433        decChk("1", one);
434        decChk("1/1", one);
435        decChk("2/2", one);
436        decChk("-1/-1", one);
437
438        decChk("-1", negOne);
439        decChk("1/-1", negOne);
440        decChk("-3/3", negOne);
441
442        decChk("2", two);
443        decChk("2/1", two);
444        decChk("-4/-2", two);
445
446        decChk("1/2", one_I_two);
447        decChk("2/4", one_I_two);
448
449        decChk("3/2", three_I_two);
450        decChk("-6/-4", three_I_two);
451
452        decChk("NaN", one_I_zero);
453        decChk("NaN", negOne_I_zero);
454    }
455
456    // Next, we test the arithmetic operations.
457    //
458    // We test them in our best guess of increasing difficultly and
459    // likelihood of having depend on a previous method. (For
460    // example, add could use sub as a subroutine.
461    //
462    // Note that our tests depend on toString and
463    // equals, which we have already tested.
464
465    @Test
466    public void testNegate() {
467        eq(zero.negate(), "0");
468        eq(one.negate(), "-1");
469        eq(negOne.negate(), "1");
470        eq(two.negate(), "-2");
471        eq(three.negate(), "-3");
472
473        eq(one_I_two.negate(), "-1/2");
474        eq(one_I_three.negate(), "-1/3");
475        eq(one_I_four.negate(), "-1/4");
476        eq(two_I_three.negate(), "-2/3");
477        eq(three_I_four.negate(), "-3/4");
478
479        eq(three_I_two.negate(), "-3/2");
480
481        eq(one_I_zero.negate(), "NaN");
482        eq(negOne_I_zero.negate(), "NaN");
483        eq(hundred_I_zero.negate(), "NaN");
484    }
485
486    @Test
487    public void testAddSimple() {
488        eq(zero.add(zero), "0");
489        eq(zero.add(one), "1");
490        eq(one.add(zero), "1");
491        eq(one.add(one), "2");
492        eq(one.add(negOne), "0");
493        eq(one.add(two), "3");
494        eq(two.add(two), "4");
495    }
496
497    @Test
498    public void testAddComplex() {
499        eq(one_I_two.add(zero), "1/2");
500        eq(one_I_two.add(one), "3/2");
501        eq(one_I_two.add(one_I_two), "1");
502        eq(one_I_two.add(one_I_three), "5/6");
503        eq(one_I_two.add(negOne), "-1/2");
504        eq(one_I_two.add(two), "5/2");
505        eq(one_I_two.add(two_I_three), "7/6");
506        eq(one_I_two.add(three_I_four), "5/4");
507
508        eq(one_I_three.add(zero), "1/3");
509        eq(one_I_three.add(two_I_three), "1");
510        eq(one_I_three.add(three_I_four), "13/12");
511    }
512
513    @Test
514    public void testAddImproper() {
515        eq(three_I_two.add(one_I_two), "2");
516        eq(three_I_two.add(one_I_three), "11/6");
517        eq(three_I_four.add(three_I_four), "3/2");
518
519        eq(three_I_two.add(three_I_two), "3");
520    }
521
522    @Test
523    public void testAddOnNaN() {
524        // each test case (addend, augend) drawn from the set
525        // ratNums x ratNaNs
526
527        for (int i = 0; i < ratNums.length; i++) {
528            for (int j = 0; j < ratNaNs.length; j++) {
529                eq(ratNums[i].add(ratNaNs[j]), "NaN");
530                eq(ratNaNs[j].add(ratNums[i]), "NaN");
531            }
532        }
533
534    }
535
536    @Test
537    public void testAddTransitively() {
538        eq(one.add(one).add(one), "3");
539        eq(one.add(one.add(one)), "3");
540        eq(zero.add(zero).add(zero), "0");
541        eq(zero.add(zero.add(zero)), "0");
542        eq(one.add(two).add(three), "6");
543        eq(one.add(two.add(three)), "6");
544
545        eq(one_I_three.add(one_I_three).add(one_I_three), "1");
546        eq(one_I_three.add(one_I_three.add(one_I_three)), "1");
547
548        eq(one_I_zero.add(one_I_zero).add(one_I_zero), "NaN");
549        eq(one_I_zero.add(one_I_zero.add(one_I_zero)), "NaN");
550
551        eq(one_I_two.add(one_I_three).add(one_I_four), "13/12");
552        eq(one_I_two.add(one_I_three.add(one_I_four)), "13/12");
553    }
554
555    @Test
556    public void testSubSimple() {
557        eq(zero.sub(one), "-1");
558        eq(zero.sub(zero), "0");
559        eq(one.sub(zero), "1");
560        eq(one.sub(one), "0");
561        eq(two.sub(one), "1");
562        eq(one.sub(negOne), "2");
563        eq(one.sub(two), "-1");
564        eq(one.sub(three), "-2");
565    }
566
567    @Test
568    public void testSubComplex() {
569        eq(one.sub(one_I_two), "1/2");
570        eq(one_I_two.sub(one), "-1/2");
571        eq(one_I_two.sub(zero), "1/2");
572        eq(one_I_two.sub(two_I_three), "-1/6");
573        eq(one_I_two.sub(three_I_four), "-1/4");
574    }
575
576    @Test
577    public void testSubImproper() {
578        eq(three_I_two.sub(one_I_two), "1");
579        eq(three_I_two.sub(one_I_three), "7/6");
580    }
581
582    /*
583     * public void testSubOnNaN() { // analogous to testAddOnNaN()
584     *
585     * for (int i=0; i<ratNums.length; i++) { for ( int j=0; j<ratNaNs.length;
586     * j++) { eq( ratNums[i].sub(ratNaNs[j]), "NaN" ); eq(
587     * ratNaNs[j].sub(ratNums[i]), "NaN" ); } } }
588     */
589    @Test
590    public void testSubTransitively() {
591        // subtraction is not transitive; testing that operation is
592        // correct when *applied transitivitely*, not that it obeys
593        // the transitive property
594
595        eq(one.sub(one).sub(one), "-1");
596        eq(one.sub(one.sub(one)), "1");
597        eq(zero.sub(zero).sub(zero), "0");
598        eq(zero.sub(zero.sub(zero)), "0");
599        eq(one.sub(two).sub(three), "-4");
600        eq(one.sub(two.sub(three)), "2");
601
602        eq(one_I_three.sub(one_I_three).sub(one_I_three), "-1/3");
603        eq(one_I_three.sub(one_I_three.sub(one_I_three)), "1/3");
604
605        // eq( one_I_zero.sub(one_I_zero).sub(one_I_zero), "NaN" );
606        // eq( one_I_zero.sub(one_I_zero.sub(one_I_zero)), "NaN" );
607
608        eq(one_I_two.sub(one_I_three).sub(one_I_four), "-1/12");
609        eq(one_I_two.sub(one_I_three.sub(one_I_four)), "5/12");
610    }
611
612    @Test
613    public void testMulProperties() {
614        // zero property
615        for (int i = 0; i < ratNonNaNs.length; i++) {
616            eq(zero.mul(ratNonNaNs[i]), "0");
617            eq(ratNonNaNs[i].mul(zero), "0");
618        }
619
620        // one property
621        for (int i = 0; i < ratNonNaNs.length; i++) {
622            eq(one.mul(ratNonNaNs[i]), ratNonNaNs[i].toString());
623            eq(ratNonNaNs[i].mul(one), ratNonNaNs[i].toString());
624        }
625
626        // negOne property
627        for (int i = 0; i < ratNonNaNs.length; i++) {
628            eq(negOne.mul(ratNonNaNs[i]), ratNonNaNs[i].negate().toString());
629            eq(ratNonNaNs[i].mul(negOne), ratNonNaNs[i].negate().toString());
630        }
631    }
632
633    @Test
634    public void testMulSimple() {
635        eq(two.mul(two), "4");
636        eq(two.mul(three), "6");
637        eq(three.mul(two), "6");
638    }
639
640    @Test
641    public void testMulComplex() {
642        eq(one_I_two.mul(two), "1");
643        eq(two.mul(one_I_two), "1");
644        eq(one_I_two.mul(one_I_two), "1/4");
645        eq(one_I_two.mul(one_I_three), "1/6");
646        eq(one_I_three.mul(one_I_two), "1/6");
647    }
648
649    @Test
650    public void testMulImproper() {
651        eq(three_I_two.mul(one_I_two), "3/4");
652        eq(three_I_two.mul(one_I_three), "1/2");
653        eq(three_I_two.mul(three_I_four), "9/8");
654        eq(three_I_two.mul(three_I_two), "9/4");
655    }
656
657    @Test
658    public void testMulOnNaN() {
659        // analogous to testAddOnNaN()
660
661        for (int i = 0; i < ratNums.length; i++) {
662            for (int j = 0; j < ratNaNs.length; j++) {
663                eq(ratNums[i].mul(ratNaNs[j]), "NaN");
664                eq(ratNaNs[j].mul(ratNums[i]), "NaN");
665            }
666        }
667    }
668
669    @Test
670    public void testMulTransitively() {
671        eq(one.mul(one).mul(one), "1");
672        eq(one.mul(one.mul(one)), "1");
673        eq(zero.mul(zero).mul(zero), "0");
674        eq(zero.mul(zero.mul(zero)), "0");
675        eq(one.mul(two).mul(three), "6");
676        eq(one.mul(two.mul(three)), "6");
677
678        eq(one_I_three.mul(one_I_three).mul(one_I_three), "1/27");
679        eq(one_I_three.mul(one_I_three.mul(one_I_three)), "1/27");
680
681        eq(one_I_zero.mul(one_I_zero).mul(one_I_zero), "NaN");
682        eq(one_I_zero.mul(one_I_zero.mul(one_I_zero)), "NaN");
683
684        eq(one_I_two.mul(one_I_three).mul(one_I_four), "1/24");
685        eq(one_I_two.mul(one_I_three.mul(one_I_four)), "1/24");
686    }
687
688    @Test
689    public void testDivSimple() {
690        eq(zero.div(zero), "NaN");
691        eq(zero.div(one), "0");
692        eq(one.div(zero), "NaN");
693        eq(one.div(one), "1");
694        eq(one.div(negOne), "-1");
695        eq(one.div(two), "1/2");
696        eq(two.div(two), "1");
697    }
698
699    @Test
700    public void testDivComplex() {
701        eq(one_I_two.div(zero), "NaN");
702        eq(one_I_two.div(one), "1/2");
703        eq(one_I_two.div(one_I_two), "1");
704        eq(one_I_two.div(one_I_three), "3/2");
705        eq(one_I_two.div(negOne), "-1/2");
706        eq(one_I_two.div(two), "1/4");
707        eq(one_I_two.div(two_I_three), "3/4");
708        eq(one_I_two.div(three_I_four), "2/3");
709
710        eq(one_I_three.div(zero), "NaN");
711        eq(one_I_three.div(two_I_three), "1/2");
712        eq(one_I_three.div(three_I_four), "4/9");
713    }
714
715    @Test
716    public void testDivImproper() {
717        eq(three_I_two.div(one_I_two), "3");
718        eq(three_I_two.div(one_I_three), "9/2");
719        eq(three_I_two.div(three_I_two), "1");
720    }
721
722    @Test
723    public void testDivOnNaN() {
724        // each test case (addend, augend) drawn from the set
725        // ratNums x ratNaNs
726
727        for (int i = 0; i < ratNums.length; i++) {
728            for (int j = 0; j < ratNaNs.length; j++) {
729                eq(ratNums[i].div(ratNaNs[j]), "NaN");
730                eq(ratNaNs[j].div(ratNums[i]), "NaN");
731            }
732        }
733
734    }
735
736    @Test
737    public void testDivTransitively() {
738        // (same note as in testSubTransitively re: transitivity property)
739
740        eq(one.div(one).div(one), "1");
741        eq(one.div(one.div(one)), "1");
742        eq(zero.div(zero).div(zero), "NaN");
743        eq(zero.div(zero.div(zero)), "NaN");
744        eq(one.div(two).div(three), "1/6");
745        eq(one.div(two.div(three)), "3/2");
746
747        eq(one_I_three.div(one_I_three).div(one_I_three), "3");
748        eq(one_I_three.div(one_I_three.div(one_I_three)), "1/3");
749
750        eq(one_I_zero.div(one_I_zero).div(one_I_zero), "NaN");
751        eq(one_I_zero.div(one_I_zero.div(one_I_zero)), "NaN");
752
753        eq(one_I_two.div(one_I_three).div(one_I_four), "6");
754        eq(one_I_two.div(one_I_three.div(one_I_four)), "3/8");
755
756    }
757
758    // Finally, we test compare. We do so last, because compare may
759    // depend on sub, isNaN, and/or equals, so we want to test those
760    // methods first.
761
762    private void assertGreater(RatNum larger, RatNum smaller) {
763        assertTrue(larger.compareTo(smaller) > 0);
764        assertTrue(smaller.compareTo(larger) < 0);
765    }
766
767    @Test
768    public void testCompareToReflexive() {
769        // reflexivitiy: x.compare(x) == 0.
770        for (int i = 0; i < ratNums.length; i++) {
771            assertEquals(ratNums[i], ratNums[i]);
772        }
773    }
774
775    @Test
776    public void testCompareToNonFract() {
777        assertGreater(one, zero);
778        assertGreater(one, negOne);
779        assertGreater(two, one);
780        assertGreater(two, zero);
781        assertGreater(zero, negOne);
782    }
783
784    @Test
785    public void testCompareToFract() {
786        assertGreater(one, one_I_two);
787        assertGreater(two, one_I_three);
788        assertGreater(one, two_I_three);
789        assertGreater(two, two_I_three);
790        assertGreater(one_I_two, zero);
791        assertGreater(one_I_two, negOne);
792        assertGreater(one_I_two, negOne_I_two);
793        assertGreater(zero, negOne_I_two);
794    }
795
796    @Test
797    public void testCompareToNaNs() {
798        for (int i = 0; i < ratNaNs.length; i++) {
799            for (int j = 0; j < ratNaNs.length; j++) {
800                assertEquals(ratNaNs[i], ratNaNs[j]);
801            }
802            for (int j = 0; j < ratNonNaNs.length; j++) {
803                assertGreater(ratNaNs[i], ratNonNaNs[j]);
804            }
805        }
806    }
807
808}