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