Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 4 | class ProductDoctrineTest extends PHPUnit_Framework_TestCase |
||
| 5 | { |
||
| 6 | |||
| 7 | function setUp() |
||
| 23 | |||
| 24 | function createProductObject($id = 0) |
||
| 34 | |||
| 35 | View Code Duplication | function createNewProduct() |
|
| 48 | |||
| 49 | function createNewProductWithVariations() |
||
| 59 | |||
| 60 | //////////////////////////////////////////////////////////////////////////// |
||
| 61 | |||
| 62 | function testSaveProductReturnsIdOfProductOnSuccess() |
||
| 83 | |||
| 84 | function testSaveThrowsExceptionOnEmptyProduct() |
||
| 91 | |||
| 92 | function testSaveThrowsExceptionOnEmptyProductDetails() |
||
| 100 | |||
| 101 | function testSaveThrowsExceptionOnEmptyName() |
||
| 108 | |||
| 109 | function testSaveThrowsExceptionOnNoNameButFilledInPrice() |
||
| 116 | |||
| 117 | function testSaveIncreasesNumberOnNewProduct() |
||
| 157 | |||
| 158 | function testSavePersistsItselfAndCanSaveAgainStillHavingTheSameNumber() |
||
| 187 | |||
| 188 | |||
| 189 | function testSaveStateAccountIdInProductDetailsDoesntChangeOtherValues() |
||
| 224 | |||
| 225 | function testChangeProductNameSavesAsNewDetail() |
||
| 253 | |||
| 254 | function testChangeProductPriceSavesAsNewDetail() |
||
| 282 | |||
| 283 | function testDetailsIsNotUpdatedWhenErrorInTranslation() |
||
| 313 | |||
| 314 | public function testLoadEarlierDetails() |
||
| 341 | |||
| 342 | public function testShowInShop() |
||
| 361 | |||
| 362 | function testSetAttributeGroupThrowsExceptionOnWhenNotSavedWithVariations() |
||
| 378 | |||
| 379 | View Code Duplication | function testSetAttributeGroup() |
|
| 390 | |||
| 391 | function testGetAttributeGroups() |
||
| 434 | |||
| 435 | /* |
||
| 436 | function testMaxNumberIncrementsOnePrProductAdded() |
||
| 437 | { |
||
| 438 | $product = $this->createProductObject(); |
||
| 439 | $this->assertEquals(0, $product->getMaxNumber()); |
||
| 440 | $product = $this->createNewProduct(); |
||
| 441 | $this->assertEquals(1, $product->getMaxNumber()); |
||
| 442 | } |
||
| 443 | |||
| 444 | function testProductCanGetNumberIfOtherProductDontNeedItAnymore() |
||
| 445 | { |
||
| 446 | $product = new Product($this->kernel); |
||
| 447 | |||
| 448 | $number = $product->getMaxNumber() + 1; |
||
| 449 | |||
| 450 | $new_number = $number + 1; |
||
| 451 | if (!$product->save(array('number' => $number, 'name' => 'Test', 'price' => 20, 'unit' => 1))) { |
||
| 452 | $product->error->view(); |
||
| 453 | } |
||
| 454 | |||
| 455 | if (!$product->save(array('number' => $new_number, 'name' => 'Test', 'price' => 20, 'unit' => 1))) { |
||
| 456 | $product->error->view(); |
||
| 457 | } |
||
| 458 | |||
| 459 | $new_product = new Product($this->kernel); |
||
| 460 | $array = array('number' => $number, 'name' => 'Test overtager nummer', 'price' => 20, 'unit' => 1); |
||
| 461 | if (!$new_product->save($array)) { |
||
| 462 | $new_product->error->view(); |
||
| 463 | } |
||
| 464 | |||
| 465 | $this->assertEquals($number, $new_product->get('number')); |
||
| 466 | } |
||
| 467 | |||
| 468 | function testDeleteAProduct() |
||
| 469 | { |
||
| 470 | $product = $this->createNewProduct(); |
||
| 471 | $this->assertTrue($product->delete()); |
||
| 472 | $this->assertFalse($product->isActive()); |
||
| 473 | } |
||
| 474 | |||
| 475 | function testUnDeleteAProduct() |
||
| 476 | { |
||
| 477 | $product = $this->createNewProduct(); |
||
| 478 | $product->delete(); |
||
| 479 | $this->assertFalse($product->isActive()); |
||
| 480 | $this->assertTrue($product->undelete()); |
||
| 481 | $this->assertTrue($product->isActive()); |
||
| 482 | } |
||
| 483 | |||
| 484 | function testAProductCanStillBeLoadedEvenIfDeleted() |
||
| 485 | { |
||
| 486 | $product = $this->createNewProduct(); |
||
| 487 | $product_id = $product->get('id'); |
||
| 488 | $product->delete(); |
||
| 489 | |||
| 490 | $deletedproduct = $this->createProductObject($product_id); |
||
| 491 | |||
| 492 | $this->assertEquals($product->get('id'), $deletedproduct->get('id')); |
||
| 493 | $this->assertEquals($product->get('name'), $deletedproduct->get('name')); |
||
| 494 | $this->assertEquals($product->get('price'), $deletedproduct->get('price')); |
||
| 495 | } |
||
| 496 | |||
| 497 | function testCopyProduct() |
||
| 498 | { |
||
| 499 | $product = $this->createNewProduct(); |
||
| 500 | $new_id = $product->copy(); |
||
| 501 | |||
| 502 | $newproduct = $this->createProductObject($new_id); |
||
| 503 | |||
| 504 | $this->assertEquals(2, $newproduct->get('number')); |
||
| 505 | $this->assertEquals('Test (kopi)', $newproduct->get('name')); |
||
| 506 | } |
||
| 507 | |||
| 508 | function testIsFilledInReturnsZeroWhenNoProductsHasBeenCreated() |
||
| 509 | { |
||
| 510 | $product = $this->createProductObject(); |
||
| 511 | $this->assertEquals(0, $product->isFilledIn()); |
||
| 512 | } |
||
| 513 | |||
| 514 | function testSetRelatedProductReturnsTrueOnSuccessAndOneProductIsReturned() |
||
| 515 | { |
||
| 516 | $product = $this->createNewProduct(); |
||
| 517 | $product_to_relate = $this->createNewProduct(); |
||
| 518 | |||
| 519 | $this->assertTrue($product->setRelatedProduct($product_to_relate->getId())); |
||
| 520 | |||
| 521 | $this->assertEquals(1, count($product->getRelatedProducts())); |
||
| 522 | } |
||
| 523 | |||
| 524 | |||
| 525 | |||
| 526 | function testRemoveAttributeGroup() |
||
| 527 | { |
||
| 528 | $product = $this->createNewProductWithVariations(); |
||
| 529 | $product->setAttributeGroup(1); |
||
| 530 | $this->assertTrue($product->removeAttributeGroup(1)); |
||
| 531 | } |
||
| 532 | |||
| 533 | |||
| 534 | |||
| 535 | function testGetVariationThrowsExceptionWhenNoGroupsAdded() |
||
| 536 | { |
||
| 537 | $product = $this->createNewProductWithVariations(); |
||
| 538 | try { |
||
| 539 | $product->getVariation(); |
||
| 540 | $this->assertTrue(false, 'No exception thrown'); |
||
| 541 | } |
||
| 542 | catch (Exception $e) { |
||
| 543 | $this->assertTrue(true); |
||
| 544 | } |
||
| 545 | |||
| 546 | } |
||
| 547 | |||
| 548 | function testGetVariation() |
||
| 549 | { |
||
| 550 | $product = $this->createNewProductWithVariations(); |
||
| 551 | $group = new Intraface_modules_product_Attribute_Group; |
||
| 552 | $group->name = 'Test1'; |
||
| 553 | $group->save(); |
||
| 554 | $group->load(); |
||
| 555 | $product->setAttributeGroup($group->getId()); |
||
| 556 | |||
| 557 | $this->assertTrue(is_object($product->getVariation())); |
||
| 558 | |||
| 559 | |||
| 560 | } |
||
| 561 | |||
| 562 | function testGetVariations() |
||
| 563 | { |
||
| 564 | $product = $this->createNewProductWithVariations(); |
||
| 565 | $group = new Intraface_modules_product_Attribute_Group; |
||
| 566 | $group->name = 'color'; |
||
| 567 | $group->attribute[0]->name = 'red'; |
||
| 568 | $group->attribute[1]->name = 'blue'; |
||
| 569 | $group->save(); |
||
| 570 | $product->setAttributeGroup($group->getId()); |
||
| 571 | |||
| 572 | |||
| 573 | $group = new Intraface_modules_product_Attribute_Group; |
||
| 574 | $group->name = 'size'; |
||
| 575 | $group->attribute[0]->name = 'small'; |
||
| 576 | $group->attribute[1]->name = 'medium'; |
||
| 577 | $group->save(); |
||
| 578 | $product->setAttributeGroup($group->getId()); |
||
| 579 | |||
| 580 | $variation = $product->getVariation(); |
||
| 581 | $variation->product_id = 1; |
||
| 582 | $variation->setAttributesFromArray(array('attribute1' => 1, 'attribute2' => 3)); |
||
| 583 | $variation->save(); |
||
| 584 | $detail = $variation->getDetail(); |
||
| 585 | $detail->price_difference = 0; |
||
| 586 | $detail->weight_difference = 0; |
||
| 587 | $detail->save(); |
||
| 588 | |||
| 589 | $variation = $product->getVariation(); |
||
| 590 | $variation->product_id = 1; |
||
| 591 | $variation->setAttributesFromArray(array('attribute1' => 2, 'attribute2' => 4)); |
||
| 592 | $variation->save(); |
||
| 593 | $detail = $variation->getDetail(); |
||
| 594 | $detail->price_difference = 0; |
||
| 595 | $detail->weight_difference = 0; |
||
| 596 | $detail->save(); |
||
| 597 | |||
| 598 | |||
| 599 | $variations = $product->getVariations(); |
||
| 600 | |||
| 601 | $this->assertEquals(2, $variations->count()); |
||
| 602 | $variation = $variations->getFirst(); |
||
| 603 | $this->assertEquals(1, $variation->getId()); |
||
| 604 | $this->assertEquals('red', $variation->attribute1->attribute->getName()); |
||
| 605 | $this->assertEquals('color', $variation->attribute1->attribute->group->getName()); |
||
| 606 | |||
| 607 | $this->assertEquals('small', $variation->attribute2->attribute->getName()); |
||
| 608 | $this->assertEquals('size', $variation->attribute2->attribute->group->getName()); |
||
| 609 | |||
| 610 | } |
||
| 611 | |||
| 612 | function testGetPriceInCurrency() |
||
| 613 | { |
||
| 614 | require_once 'tests/unit/stubs/Fake/Intraface/modules/currency/Currency.php'; |
||
| 615 | $currency = new Fake_Intraface_modules_currency_Currency; |
||
| 616 | require_once 'tests/unit/stubs/Fake/Intraface/modules/currency/Currency/ExchangeRate.php'; |
||
| 617 | $currency->product_price_exchange_rate = new Fake_Intraface_modules_currency_Currency_ExchangeRate; |
||
| 618 | require_once 'tests/unit/stubs/Fake/Ilib/Variable/Float.php'; |
||
| 619 | $currency->product_price_exchange_rate->rate = new Fake_Ilib_Variable_Float; |
||
| 620 | $currency->product_price_exchange_rate->rate->iso = 745.23; |
||
| 621 | |||
| 622 | $product = new Product($this->kernel); |
||
| 623 | $product->save(array('name' => 'test', 'price' => 200, 'unit' => 1)); |
||
| 624 | $product->load(); |
||
| 625 | |||
| 626 | $this->assertEquals(26.84, $product->getDetails()->getPriceInCurrency($currency)->getAsIso()); |
||
| 627 | |||
| 628 | |||
| 629 | |||
| 630 | } |
||
| 631 | */ |
||
| 632 | } |
||
| 633 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.