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