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