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