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