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