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