001    package hw3.test;
002    
003    import hw3.*;
004    
005    import org.junit.Test;
006    import org.junit.BeforeClass;
007    import static org.junit.Assert.*;
008    import 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     */
017    public 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    }