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