001package hw3.test;
002
003import hw3.*;
004
005import org.junit.Test;
006import org.junit.BeforeClass;
007import static org.junit.Assert.*;
008import 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 */
020public 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
170  ///////////////////////////////////////////////////////////////////////////////////////
171  ////  Constructor
172  ///////////////////////////////////////////////////////////////////////////////////////   
173  
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 testTwoArgConstructorPos() {
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
192  @Test
193  public void testTwoArgConstructorNeg() {
194    new RatNum(-1, 2);      
195  }
196
197  @Test
198  public void testTwoArgConstructorImproperFract() {
199    // improper fraction
200    new RatNum(3, 2);
201  }
202
203  @Test
204  public void testTwoArgConstructorNaN() {
205    // NaNs
206    new RatNum(1, 0);
207    new RatNum(-1, 0);
208    new RatNum(100, 0);
209  }
210
211  ///////////////////////////////////////////////////////////////////////////////////////
212  ////  IsNaN Test
213  ///////////////////////////////////////////////////////////////////////////////////////   
214  
215  // Next, we test isNaN because it can be tested in isolation from
216  // everything except the constructors. (All instance method tests
217  // will depend on a constructor.)
218  @Test
219  public void testIsNaN() {
220    for (int i = 0; i < ratNaNs.length; i++) {
221      assertTrue(ratNaNs[i].isNaN());
222    }
223
224  }
225  @Test
226  public void testIsNotNaN() {
227    for (int i = 0; i < ratNonNaNs.length; i++) {
228      assertFalse(ratNonNaNs[i].isNaN());
229    }
230  }
231
232  ///////////////////////////////////////////////////////////////////////////////////////
233  ////  Test is Polarity, IsPositive, IsNegative
234  ///////////////////////////////////////////////////////////////////////////////////////   
235  
236  // Next, we test isPos and isNeg because we can easily test these
237  // methods without depending on any other methods (except the
238  // constructors).
239  private void assertPos(RatNum n) {
240    assertTrue(n.isPositive());
241    assertFalse(n.isNegative());
242  }
243
244  private void assertNeg(RatNum n) {
245    assertTrue(n.isNegative());
246    assertFalse(n.isPositive());
247  }
248
249  //Test Zero is not positive nor negative
250  @Test
251  public void testZeroIsNotPosNorNeg() {
252    assertFalse(zero.isPositive());
253    assertFalse(zero.isNegative());
254  }
255
256  @Test
257  public void testIsNegWholeNum() {
258    assertNeg(negOne);
259  }
260
261  @Test
262  public void testIsNegFraction(){
263    assertNeg(negOne_I_two);
264  }
265
266
267  @Test
268  public void testIsPosWholeNum(){
269    assertPos(one);
270    assertPos(two);
271    assertPos(three);
272  }
273
274  @Test
275  public void testIsPosFraction(){
276    assertPos(one_I_three);
277    assertPos(two_I_three);
278    assertPos(three_I_two);
279  }
280
281  //NaN is Special instance and is non-intuitive, See RatNum Specification
282  @Test
283  public void testNaNIsPos(){
284    assertPos(one_I_zero);
285    assertPos(negOne_I_zero); 
286    assertPos(hundred_I_zero);
287  }
288
289  ///////////////////////////////////////////////////////////////////////////////////////
290  ////  Double Value
291  ///////////////////////////////////////////////////////////////////////////////////////
292
293  // Next, we test doubleValue because the test does not require any
294  // other RatNum methods (other than constructors).
295
296  // asserts that two double's are within .0000001 of one another.
297  // It is often impossible to assert that doubles are exactly equal
298  // because of the idiosyncrasies of Java's floating point math.
299  private void approxEq(double expected, double actual) {
300    assertEquals(expected, actual, .0000001);
301  }
302
303  @Test
304  public void testDoubleValueSmallNum() {
305    // use left-shift operator "<<" to create integer for 2^30
306    RatNum one_I_twoToThirty = new RatNum(1, (1 << 30));
307    double quiteSmall = 1. / Math.pow(2, 30);
308    approxEq(quiteSmall, one_I_twoToThirty.doubleValue());
309  }
310
311  @Test // Whole numbers
312  public void testDoubleValueWholeNumber() {
313    approxEq(0.0, zero.doubleValue());
314    approxEq(1.0, one.doubleValue());
315    approxEq(2.0, two.doubleValue());
316    approxEq(-1.0, negOne.doubleValue());
317  }
318
319  @Test // Fractional numbers
320  public void testDoubleValueFracNumber() {
321    approxEq(0.5, one_I_two.doubleValue());
322    approxEq(2. / 3., two_I_three.doubleValue());
323    approxEq(0.75, three_I_four.doubleValue());      
324  }
325
326  @Test // NaN double Value
327  public void testDoubleValueNaN() {
328    // To understand the use of "new Double(Double.NaN)" instead of
329    // "Double.NaN", see the Javadoc for Double.equals().
330    assertEquals(new Double(Double.NaN),
331        new Double(one_I_zero.doubleValue()));
332  }
333
334  ///////////////////////////////////////////////////////////////////////////////////////
335  ////  Float Value
336  ///////////////////////////////////////////////////////////////////////////////////////
337
338  @Test // Float Value Small Number
339  public void testFloatValueSmallNum() {
340    // use left-shift operator "<<" to create integer for 2^30
341    RatNum one_I_twoToThirty = new RatNum(1, (1 << 30));
342    double quiteSmall = 1. / Math.pow(2, 30);
343    approxEq(quiteSmall, one_I_twoToThirty.floatValue());
344  }
345
346  @Test // Float Value Whole Number
347  public void testFloatValueWholeNumber() {
348    approxEq(0.0, zero.floatValue());
349    approxEq(1.0, one.floatValue());
350    approxEq(2.0, two.floatValue());
351    approxEq(-1.0, negOne.floatValue());
352  }
353
354  @Test // Fractional numbers
355  public void testFloatValueFracNumber() {
356    approxEq(0.5, one_I_two.floatValue());
357    approxEq(2. / 3., two_I_three.floatValue());
358    approxEq(0.75, three_I_four.floatValue());      
359  }
360
361  @Test // NaN Float Value
362  public void testFloatValueNaN() {
363    // To understand the use of "new Float(Float.NaN)" instead of
364    // "Float.NaN", see the Javadoc for Float.equals().
365    assertEquals(new Float(Float.NaN),
366        new Float(one_I_zero.floatValue()));
367  }
368
369  ///////////////////////////////////////////////////////////////////////////////////////
370  ////  Int Value
371  ///////////////////////////////////////////////////////////////////////////////////////    
372
373  @Test
374  public void testIntValueUnsupported() {
375    if (false) {
376      // Note that these tests fail because our RatNum implementation
377      // can't represent the fractions in question. Can you think of
378      // a tweak to the representation invariant which would allow us
379      // to represent these values?
380      assertEquals("(MIN_VALUE+1)/MIN_VALUE should round to 1",
381          1, new RatNum(Integer.MIN_VALUE + 1, Integer.MIN_VALUE).intValue());
382      assertEquals("1/MIN_VALUE should round to 0",
383          0, new RatNum(1, Integer.MIN_VALUE).intValue());
384    }
385  }
386
387  @Test
388  public void testIntValueWithOutRound() {
389    assertEquals("0 should round to 0", 0, zero.intValue());
390    assertEquals("1 should round to 1", 1, one.intValue());
391    assertEquals("-1 should round to -1", -1, negOne.intValue());
392  }
393
394  @Test
395  public void testIntValueWithRoundtoPosOne() {
396    assertEquals("1/2 should round to 1", 1, one_I_two.intValue());
397    assertEquals("2/3 should round to 1", 1, two_I_three.intValue());
398    assertEquals("3/4 should round to 1", 1, three_I_four.intValue());
399  }
400
401  @Test
402  public void testIntValueWithRoundtoNegOne() {
403    assertEquals("-1/2 should round to -1", -1, one_I_two.negate().intValue());
404    assertEquals("-2/3 should round to -1", -1, two_I_three.negate().intValue());
405    assertEquals("-3/4 should round to -1", -1, three_I_four.negate().intValue());
406  }
407
408  @Test
409  public void testIntValueWithRoundMaxValue() {
410    assertEquals("MAX_VALUE should round to MAX_VALUE",
411        Integer.MAX_VALUE, new RatNum(Integer.MAX_VALUE).intValue());      
412    assertEquals("MAX_VALUE/2 should round to (MAX_VALUE/2)+1",
413        (Integer.MAX_VALUE / 2) + 1, new RatNum(Integer.MAX_VALUE, 2).intValue());           
414  }
415
416  @Test  //Ensure 1 / Max Value == 0
417  public void testIntValueWithRoundOneOverMaxValue() {
418    assertEquals("1/MAX_VALUE should round to 0",
419        0, new RatNum(1, Integer.MAX_VALUE).intValue());
420  }
421
422  @Test  //Ensure Max Value / Max Value == 1
423  public void testIntValueMaxValueDivByMaxValue() {
424    assertEquals("MAX_VALUE/MAX_VALUE should round to 1",
425        1, new RatNum(Integer.MAX_VALUE, Integer.MAX_VALUE).intValue());
426    assertEquals("(MAX_VALUE-1)/MAX_VALUE should round to 1",
427        1, new RatNum(Integer.MAX_VALUE - 1, Integer.MAX_VALUE).intValue());
428  }
429
430  @Test  
431  public void testIntValueWithRoundMinValue() {
432    assertEquals("MIN_VALUE should round to MIN_VALUE",
433        Integer.MIN_VALUE, new RatNum(Integer.MIN_VALUE).intValue());
434    assertEquals("MIN_VALUE/2 should round to (MIN_VALUE/2)",
435        (Integer.MIN_VALUE / 2), new RatNum(Integer.MIN_VALUE, 2).intValue());      
436  }
437
438  @Test //Ensure Min Value / Min Value == 1
439  public void testIntValueMinValueDivByMinValue() {
440    assertEquals("MIN_VALUE/MIN_VALUE should round to 1",
441        1, new RatNum(Integer.MIN_VALUE, Integer.MIN_VALUE).intValue());
442  }
443
444  ///////////////////////////////////////////////////////////////////////////////////////
445  ////  Equals
446  ///////////////////////////////////////////////////////////////////////////////////////      
447
448  // Next, we test the equals method because that can be tested in
449  // isolation from everything except the constructor and maybe
450  // isNaN, which we just tested.
451  // Additionally, this method will be very useful for testing other
452  // methods.
453
454  /**
455   * This test check is equals is reflexive. In other words that x.equals(x)
456   * is always true.
457   */
458  @Test
459  public void testEqualsReflexive() {
460    for (int i = 0; i < ratNums.length; i++) {
461      assertEquals(ratNums[i], ratNums[i]);
462    }
463  }
464
465  @Test
466  public void testEqualsSimple() {
467    // Some simple cases.
468    assertEquals(one, one);
469    assertEquals(one.add(one), two);
470    // including negitives:
471    assertEquals(negOne, negOne);
472  }
473
474  @Test
475  public void testEqualsSimpleWithDiffObjects() {
476    // Some simple cases where the objects are different but
477    // represent the same rational number. That is, x != y but
478    // x.equals(y).
479    assertEquals(new RatNum(1, 1), new RatNum(1, 1));
480    assertEquals(new RatNum(1, 2), new RatNum(1, 2));
481  }
482
483  @Test
484  public void testEqualsNotReducedFormOne() {
485    // Check that equals works on fractions that were not
486    // constructed in reduced form.
487    assertEquals(one, new RatNum(2, 2));
488    assertEquals(new RatNum(2, 2), one);
489  }
490
491  @Test
492  public void testEqualsNotReducedFormNegOne() {
493    // including negitives:
494    assertEquals(negOne, new RatNum(-9, 9));
495    assertEquals(new RatNum(-9, 9), negOne);
496  }
497
498  @Test
499  public void testEqualsNotReducedFormFraction() {
500    // including double negitives:
501    assertEquals(one_I_two, new RatNum(-13, -26));
502    assertEquals(new RatNum(-13, -26), one_I_two);
503  }
504
505  @Test
506  public void testEqualsNaN() {
507    // Check that all NaN's are equals to one another.
508    assertEquals(one_I_zero, one_I_zero);
509    assertEquals(one_I_zero, negOne_I_zero);
510    assertEquals(one_I_zero, hundred_I_zero);
511  }
512
513  @Test
514  public void testEqualsForFalsePos() {
515    // Some simple cases checking for false positives.
516    assertThat(one, not(zero));
517    assertThat(zero, not(one));
518    assertThat(one, not(two));
519    assertThat(two, not(one));
520  }
521
522  @Test
523  public void testEqualsForSign() {
524    // Check that equals does not neglect sign.
525    assertThat(one, not(negOne));
526    assertThat(negOne, not(one));
527  }
528
529  @Test
530  public void testEqualsNotFalsePosWithFracs() {
531    // Check that equals does not return false positives on
532    // fractions.
533    assertThat(one, not(one_I_two));
534    assertThat(one_I_two, not(one));
535    assertThat(one, not(three_I_two));
536    assertThat(three_I_two, not(one));
537  }
538
539  ///////////////////////////////////////////////////////////////////////////////////////
540  ////  String
541  ///////////////////////////////////////////////////////////////////////////////////////     
542
543  // Now that we have verified equals, we will use it in the
544  // rest or our tests.
545
546  // Next, we test the toString and valueOf methods because we can test
547  // them isolation of everything except the constructor and equals,
548  // and they will be useful methods to aid with testing other
549  // methods. (In some cases, it is easier to use valueOf("1/2") than
550  // new RatNum(1, 2) as you will see below.)
551
552  // Note that "eq" calls "toString" on its first argument.
553  @Test
554  public void testToStringSimple() {
555    eq(zero, "0");
556
557    eq(one, "1");
558
559    RatNum four = new RatNum(4);
560    eq(four, "4");
561
562    eq(negOne, "-1");
563
564    RatNum negFive = new RatNum(-5);
565    eq(negFive, "-5");
566
567    RatNum negZero = new RatNum(-0);
568    eq(negZero, "0");
569  }
570
571  @Test
572  public void testToStringFractions() {
573    RatNum one_I_two = new RatNum(1, 2);
574    eq(one_I_two, "1/2");
575
576    RatNum three_I_two = new RatNum(3, 2);
577    eq(three_I_two, "3/2");
578
579    RatNum negOne_I_thirteen = new RatNum(-1, 13);
580    eq(negOne_I_thirteen, "-1/13");
581
582    RatNum fiftyThree_I_seven = new RatNum(53, 7);
583    eq(fiftyThree_I_seven, "53/7");
584
585    RatNum twentySeven_I_thirteen = new RatNum(27, 13);
586    eq(twentySeven_I_thirteen, "27/13");
587  }
588
589  @Test
590  public void testToStringNaN() {
591    RatNum one_I_zero = new RatNum(1, 0);
592    eq(one_I_zero, "NaN");
593
594    RatNum two_I_zero = new RatNum(2, 0);
595    eq(two_I_zero, "NaN");
596
597    RatNum negOne_I_zero = new RatNum(-1, 0);
598    eq(negOne_I_zero, "NaN");
599
600    RatNum zero_I_zero = new RatNum(0, 0);
601    eq(zero_I_zero, "NaN");
602
603    RatNum negHundred_I_zero = new RatNum(-100, 0);
604    eq(negHundred_I_zero, "NaN");
605  }
606
607  @Test
608  public void testToStringOneDenom() {
609    RatNum two_I_one = new RatNum(2, 1);
610    eq(two_I_one, "2");
611
612    RatNum zero_I_one = new RatNum(0, 1);
613    eq(zero_I_one, "0");
614  }
615
616  @Test
617  public void testToStringReduction() {
618    RatNum negOne_I_negTwo = new RatNum(-1, -2);
619    eq(negOne_I_negTwo, "1/2");
620
621    RatNum two_I_four = new RatNum(2, 4);
622    eq(two_I_four, "1/2");
623
624    RatNum six_I_four = new RatNum(6, 4);
625    eq(six_I_four, "3/2");
626
627    RatNum negHundred_I_negHundred = new RatNum(-100, -100);
628    eq(negHundred_I_negHundred, "1");
629  }
630
631  ///////////////////////////////////////////////////////////////////////////////////////
632  ////  Value Of
633  /////////////////////////////////////////////////////////////////////////////////////// 
634
635  // helper function, "decode-and-check"
636  private void decChk(String s, RatNum expected) {
637    RatNum.valueOf(s).equals(expected);
638  }
639
640  // Note that decChk calls valueOf.
641  @Test
642  public void testValueOf() {
643    decChk("0", zero);
644    decChk("1", one);        
645  }
646
647  @Test
648  public void testValueOfPosOne() {
649    decChk("1/1", one);
650    decChk("2/2", one);
651    decChk("-1/-1", one);
652  }
653
654  @Test
655  public void testValueOfNegOne() {
656    decChk("-1", negOne);
657    decChk("1/-1", negOne);
658    decChk("-3/3", negOne);
659  }
660
661  @Test
662  public void testValueOfPosTwo() {
663    decChk("2", two);
664    decChk("2/1", two);
665    decChk("-4/-2", two);
666  }
667
668  @Test
669  public void testValueOfOneHalf() {
670    decChk("1/2", one_I_two);
671    decChk("2/4", one_I_two);
672  }
673
674  @Test
675  public void testValueOfThreeHalfs() {
676    decChk("3/2", three_I_two);
677    decChk("-6/-4", three_I_two);
678  }
679
680  @Test
681  public void testValueOfNa() {
682    decChk("NaN", one_I_zero);
683    decChk("NaN", negOne_I_zero);
684  }
685
686  ///////////////////////////////////////////////////////////////////////////////////////
687  ////  Negate
688  /////////////////////////////////////////////////////////////////////////////////////// 
689
690  // Next, we test the arithmetic operations.
691  //
692  // We test them in our best guess of increasing difficultly and
693  // likelihood of having depend on a previous method. (For
694  // example, add could use sub as a subroutine.
695  //
696  // Note that our tests depend on toString and
697  // equals, which we have already tested.
698
699  @Test
700  public void testNegateNaN() {
701    eq(one_I_zero.negate(), "NaN");
702    eq(negOne_I_zero.negate(), "NaN");
703    eq(hundred_I_zero.negate(), "NaN");
704  }
705
706  @Test
707  public void testNegateToPos() {
708    eq(zero.negate(), "0");
709    eq(negOne.negate(), "1");
710  }
711
712  @Test
713  public void testNegateToNeg() {
714    eq(one.negate(), "-1");
715    eq(two.negate(), "-2");
716    eq(one_I_two.negate(), "-1/2");
717    eq(one_I_three.negate(), "-1/3");
718    eq(three_I_four.negate(), "-3/4");
719    eq(three_I_two.negate(), "-3/2");
720  }
721
722  ///////////////////////////////////////////////////////////////////////////////////////
723  ////  Add Test
724  /////////////////////////////////////////////////////////////////////////////////////// 
725
726  @Test
727  public void testAddSimple() {
728    eq(zero.add(zero), "0");
729    eq(zero.add(one), "1");
730    eq(one.add(zero), "1");
731    eq(one.add(one), "2");
732    eq(one.add(negOne), "0");
733    eq(one.add(two), "3");
734    eq(two.add(two), "4");
735  }
736
737  @Test
738  public void testAddComplexToOne() {
739    eq(one_I_two.add(one_I_two), "1");
740    eq(one_I_three.add(two_I_three), "1");
741  }
742
743  @Test
744  public void testAddComplex() {
745    eq(one_I_two.add(zero), "1/2");
746    eq(one_I_two.add(one), "3/2");  
747    eq(one_I_two.add(one_I_three), "5/6");
748    eq(one_I_two.add(negOne), "-1/2");
749    eq(one_I_two.add(two), "5/2");
750    eq(one_I_two.add(two_I_three), "7/6");  
751    eq(one_I_three.add(three_I_four), "13/12");
752  }
753
754  @Test
755  public void testAddImproper() {
756    eq(three_I_two.add(one_I_two), "2");
757    eq(three_I_two.add(one_I_three), "11/6");
758    eq(three_I_four.add(three_I_four), "3/2");
759    eq(three_I_two.add(three_I_two), "3");
760  }
761
762  @Test
763  public void testAddOnNaN() {
764    // each test case (addend, augend) drawn from the set
765    // ratNums x ratNaNs
766
767    for (int i = 0; i < ratNums.length; i++) {
768      for (int j = 0; j < ratNaNs.length; j++) {
769        eq(ratNums[i].add(ratNaNs[j]), "NaN");
770        eq(ratNaNs[j].add(ratNums[i]), "NaN");
771      }
772    }
773  }
774
775  // Testing Add Transitivity Property
776
777  @Test
778  public void testAddTransitivelyZero() {
779    eq(zero.add(zero).add(zero), "0");
780    eq(zero.add(zero.add(zero)), "0");
781  }
782
783  @Test
784  public void testAddTransitivelyOne() {
785    eq(one_I_three.add(one_I_three).add(one_I_three), "1");
786    eq(one_I_three.add(one_I_three.add(one_I_three)), "1");
787  }
788
789  @Test
790  public void testAddTransitivelyWholeNum() {
791    eq(one.add(one).add(one), "3");
792    eq(one.add(one.add(one)), "3");
793
794    eq(one.add(two).add(three), "6");
795    eq(one.add(two.add(three)), "6");      
796  }
797
798  @Test
799  public void testAddTransitivelyNaN() {
800    eq(one_I_zero.add(one_I_zero).add(one_I_zero), "NaN");
801    eq(one_I_zero.add(one_I_zero.add(one_I_zero)), "NaN");
802  }
803
804  @Test
805  public void testAddTransitivelyFractions() {
806    eq(one_I_two.add(one_I_three).add(one_I_four), "13/12");
807    eq(one_I_two.add(one_I_three.add(one_I_four)), "13/12");
808  }
809
810  ///////////////////////////////////////////////////////////////////////////////////////
811  ////  Subtraction Test
812  ///////////////////////////////////////////////////////////////////////////////////////   
813  
814  @Test
815  public void testSubSimple() {        
816    eq(zero.sub(zero), "0");
817    eq(one.sub(zero), "1");
818    eq(one.sub(one), "0");
819    eq(two.sub(one), "1");
820    eq(one.sub(negOne), "2");       
821  }
822
823  @Test
824  public void testSubSimpleToNeg() {
825    eq(zero.sub(one), "-1");
826    eq(one.sub(two), "-1");
827    eq(one.sub(three), "-2");
828  }
829
830  @Test
831  public void testSubComplex() {
832    eq(one.sub(one_I_two), "1/2");
833    eq(one_I_two.sub(one), "-1/2");
834    eq(one_I_two.sub(zero), "1/2");
835    eq(one_I_two.sub(two_I_three), "-1/6");
836    eq(one_I_two.sub(three_I_four), "-1/4");
837  }
838
839  @Test
840  public void testSubImproper() {
841    eq(three_I_two.sub(one_I_two), "1");
842    eq(three_I_two.sub(one_I_three), "7/6");
843  }
844
845  @Test
846  public void testSubOnNaN() {
847    // analogous to testAddOnNaN()
848
849    for (int i = 0; i < ratNums.length; i++) {
850      for (int j = 0; j < ratNaNs.length; j++) {
851        eq(ratNums[i].sub(ratNaNs[j]), "NaN");
852        eq(ratNaNs[j].sub(ratNums[i]), "NaN");
853      }
854    }
855  }
856
857  // Subtraction transitivity Tests
858  
859  @Test
860  public void testSubTransitivetyWholeNumsToNonZero() {
861    // subtraction is not transitive; testing that operation is
862    // correct when *applied transitivitely*, not that it obeys
863    // the transitive property
864
865    eq(one.sub(one).sub(one), "-1");
866    eq(one.sub(one.sub(one)), "1");
867    eq(one.sub(two).sub(three), "-4");
868    eq(one.sub(two.sub(three)), "2");
869  }
870
871  @Test
872  public void testSubTransitivetyWholeNumsToZero() {
873    eq(zero.sub(zero).sub(zero), "0");
874    eq(zero.sub(zero.sub(zero)), "0");      
875  }
876
877  @Test
878  public void testSubTransitivelyComplex() {
879    eq(one_I_three.sub(one_I_three).sub(one_I_three), "-1/3");
880    eq(one_I_three.sub(one_I_three.sub(one_I_three)), "1/3");
881
882    eq(one_I_two.sub(one_I_three).sub(one_I_four), "-1/12");
883    eq(one_I_two.sub(one_I_three.sub(one_I_four)), "5/12");
884  }
885
886  @Test
887  public void testSubTransitivelyNaN() {
888    eq(one_I_zero.sub(one_I_zero).sub(one_I_zero), "NaN");
889    eq(one_I_zero.sub(one_I_zero.sub(one_I_zero)), "NaN");
890  }
891
892  ///////////////////////////////////////////////////////////////////////////////////////
893  ////  Multiplication Test
894  /////////////////////////////////////////////////////////////////////////////////////// 
895  
896  //Test multiplication properties
897  @Test
898  public void testMulPropertiesZero() {
899    // zero property
900    for (int i = 0; i < ratNonNaNs.length; i++) {
901      eq(zero.mul(ratNonNaNs[i]), "0");
902      eq(ratNonNaNs[i].mul(zero), "0");
903    }
904  }
905
906  @Test
907  public void testMulPropertiesOne() {
908    // one property
909    for (int i = 0; i < ratNonNaNs.length; i++) {
910      eq(one.mul(ratNonNaNs[i]), ratNonNaNs[i].toString());
911      eq(ratNonNaNs[i].mul(one), ratNonNaNs[i].toString());
912    }
913  }
914
915  @Test
916  public void testMulPropertiesNegOne() {
917    // negOne property
918    for (int i = 0; i < ratNonNaNs.length; i++) {
919      eq(negOne.mul(ratNonNaNs[i]), ratNonNaNs[i].negate().toString());
920      eq(ratNonNaNs[i].mul(negOne), ratNonNaNs[i].negate().toString());
921    }
922  }
923
924  @Test
925  public void testMulSimple() {
926    eq(two.mul(two), "4");
927    eq(two.mul(three), "6");
928    eq(three.mul(two), "6");
929  }
930
931  @Test
932  public void testMulComplexToOne() {
933    eq(one_I_two.mul(two), "1");
934    eq(two.mul(one_I_two), "1");
935  }
936
937  @Test
938  public void testMulComplexToComplex() {
939    eq(one_I_two.mul(one_I_two), "1/4");
940    eq(one_I_two.mul(one_I_three), "1/6");
941    eq(one_I_three.mul(one_I_two), "1/6");
942  }
943
944  @Test
945  public void testMulImproper() {
946    eq(three_I_two.mul(one_I_two), "3/4");
947    eq(three_I_two.mul(one_I_three), "1/2");
948    eq(three_I_two.mul(three_I_four), "9/8");
949    eq(three_I_two.mul(three_I_two), "9/4");
950  }
951
952  @Test
953  public void testMulOnNaN() {
954    // analogous to testAddOnNaN()
955
956    for (int i = 0; i < ratNums.length; i++) {
957      for (int j = 0; j < ratNaNs.length; j++) {
958        eq(ratNums[i].mul(ratNaNs[j]), "NaN");
959        eq(ratNaNs[j].mul(ratNums[i]), "NaN");
960      }
961    }
962  }
963
964  @Test
965  public void testMulTransitivelyToNonZero() {
966    eq(one.mul(one).mul(one), "1");
967    eq(one.mul(one.mul(one)), "1");
968    eq(one.mul(two).mul(three), "6");
969    eq(one.mul(two.mul(three)), "6"); 
970  }
971
972  @Test
973  public void testMulTransitivelyToZero() {
974    eq(zero.mul(zero).mul(zero), "0");
975    eq(zero.mul(zero.mul(zero)), "0");
976  }
977
978  @Test
979  public void testMulTransitivelyComplex() {
980    eq(one_I_three.mul(one_I_three).mul(one_I_three), "1/27");
981    eq(one_I_three.mul(one_I_three.mul(one_I_three)), "1/27");
982
983    eq(one_I_two.mul(one_I_three).mul(one_I_four), "1/24");
984    eq(one_I_two.mul(one_I_three.mul(one_I_four)), "1/24");
985  }
986
987  @Test
988  public void testMulTransitivelyNaN() {
989    eq(one_I_zero.mul(one_I_zero).mul(one_I_zero), "NaN");
990    eq(one_I_zero.mul(one_I_zero.mul(one_I_zero)), "NaN");
991  }
992
993  ///////////////////////////////////////////////////////////////////////////////////////
994  ////  Division Test
995  /////////////////////////////////////////////////////////////////////////////////////// 
996  
997  @Test
998  public void testSimpleDivToZero() {        
999    eq(zero.div(one), "0");        
1000    eq(one.div(one), "1");
1001    eq(one.div(negOne), "-1");
1002    eq(one.div(two), "1/2");
1003    eq(two.div(two), "1");
1004  }
1005
1006  @Test
1007  public void testDivComplex() {  
1008    eq(one_I_two.div(one), "1/2");
1009    eq(one_I_two.div(one_I_two), "1");
1010    eq(one_I_two.div(one_I_three), "3/2");
1011    eq(one_I_two.div(negOne), "-1/2");
1012    eq(one_I_two.div(two), "1/4");
1013    eq(one_I_two.div(two_I_three), "3/4");
1014    eq(one_I_two.div(three_I_four), "2/3");
1015    eq(one_I_three.div(two_I_three), "1/2");
1016    eq(one_I_three.div(three_I_four), "4/9");
1017  }
1018
1019  @Test
1020  public void testDivImproper() {
1021    eq(three_I_two.div(one_I_two), "3");
1022    eq(three_I_two.div(one_I_three), "9/2");
1023    eq(three_I_two.div(three_I_two), "1");
1024  }
1025
1026  @Test
1027  public void testDivNaN() {
1028    eq(zero.div(zero), "NaN");
1029    eq(one.div(zero), "NaN");
1030    eq(one_I_two.div(zero), "NaN");
1031    eq(one_I_three.div(zero), "NaN");
1032  }
1033
1034  @Test
1035  public void testDivOnNaN() {
1036    // each test case (addend, augend) drawn from the set
1037    // ratNums x ratNaNs
1038
1039    for (int i = 0; i < ratNums.length; i++) {
1040      for (int j = 0; j < ratNaNs.length; j++) {
1041        eq(ratNums[i].div(ratNaNs[j]), "NaN");
1042        eq(ratNaNs[j].div(ratNums[i]), "NaN");
1043      }
1044    }
1045
1046  }
1047
1048  @Test
1049  public void testDivTransitivelyWholeNum() {
1050    eq(one.div(one).div(one), "1");
1051    eq(one.div(one.div(one)), "1");
1052    eq(one_I_three.div(one_I_three).div(one_I_three), "3");
1053    eq(one_I_two.div(one_I_three).div(one_I_four), "6");
1054  }
1055
1056  @Test
1057  public void testDivTransitively() {
1058    // (same note as in testSubTransitively re: transitivity property) 
1059    eq(one.div(two).div(three), "1/6");
1060    eq(one.div(two.div(three)), "3/2");    
1061    eq(one_I_three.div(one_I_three.div(one_I_three)), "1/3"); 
1062    eq(one_I_two.div(one_I_three.div(one_I_four)), "3/8");
1063  }
1064
1065  @Test
1066  public void testDivTransitivelyNaN() {
1067    eq(zero.div(zero).div(zero), "NaN");
1068    eq(zero.div(zero.div(zero)), "NaN");
1069    eq(one_I_zero.div(one_I_zero).div(one_I_zero), "NaN");
1070    eq(one_I_zero.div(one_I_zero.div(one_I_zero)), "NaN");
1071
1072  }
1073
1074  ///////////////////////////////////////////////////////////////////////////////////////
1075  ////  Compare Test
1076  /////////////////////////////////////////////////////////////////////////////////////// 
1077  
1078  // Finally, we test compare. We do so last, because compare may
1079  // depend on sub, isNaN, and/or equals, so we want to test those
1080  // methods first.
1081
1082  private void assertGreater(RatNum larger, RatNum smaller) {
1083    assertTrue(larger.compareTo(smaller) > 0);
1084    assertTrue(smaller.compareTo(larger) < 0);
1085  }
1086
1087  @Test
1088  public void testCompareToReflexive() {
1089    // reflexivitiy: x.compare(x) == 0.
1090    for (int i = 0; i < ratNums.length; i++) {
1091      assertEquals(ratNums[i], ratNums[i]);
1092    }
1093  }
1094
1095  @Test
1096  public void testCompareToNonFract() {
1097    assertGreater(one, zero);
1098    assertGreater(one, negOne);
1099    assertGreater(two, one);
1100    assertGreater(two, zero);
1101    assertGreater(zero, negOne);
1102  }
1103
1104  @Test
1105  public void testCompareToFract() {
1106    assertGreater(one, one_I_two);
1107    assertGreater(two, one_I_three);
1108    assertGreater(one, two_I_three);
1109    assertGreater(two, two_I_three);
1110    assertGreater(one_I_two, zero);
1111    assertGreater(one_I_two, negOne);
1112    assertGreater(one_I_two, negOne_I_two);
1113    assertGreater(zero, negOne_I_two);
1114  }
1115
1116  @Test
1117  public void testCompareToNaNs() {
1118    for (int i = 0; i < ratNaNs.length; i++) {
1119      for (int j = 0; j < ratNaNs.length; j++) {
1120        assertEquals(ratNaNs[i], ratNaNs[j]);
1121      }
1122      for (int j = 0; j < ratNonNaNs.length; j++) {
1123        assertGreater(ratNaNs[i], ratNonNaNs[j]);
1124      }
1125    }
1126  }
1127
1128}