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