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 }