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