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