Skip to content

Commit

Permalink
Feature/256 Transform assertEquals/assertSame in assertEqualsWithDelta (
Browse files Browse the repository at this point in the history
#257)

- Created role
- Created tests

Co-authored-by: Erison Silva <[email protected]>
  • Loading branch information
eerison and Erison Silva authored Sep 18, 2023
1 parent 66bb48b commit c71ce2a
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Rector\PHPUnit\Tests\Transform\Rector\AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRector;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRectorTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Rector\PHPUnit\Tests\Transform\Rector\AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRector\Fixture;

use PHPUnit\Framework\TestCase;

class MyTest1 extends TestCase
{
public function test()
{
$value = 10.20001;
$this->assertSame(10.20, $value);
$this->assertEquals(10.20, $value);
$this->assertEquals(10.200, $value);
$this->assertEquals('10.20', $value);
$this->assertSame(10.28, $value);
$this->assertEquals(10.2, $value);
$this->assertEquals(10, $value);
$this->assertSame(10, $value);
}
}

?>
-----
<?php

namespace Rector\PHPUnit\Tests\Transform\Rector\AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRector\Fixture;

use PHPUnit\Framework\TestCase;

class MyTest1 extends TestCase
{
public function test()
{
$value = 10.20001;
$this->assertEqualsWithDelta(10.20, $value, 0.01);
$this->assertEqualsWithDelta(10.20, $value, 0.01);
$this->assertEqualsWithDelta(10.200, $value, 0.001);
$this->assertEquals('10.20', $value);
$this->assertEqualsWithDelta(10.28, $value, 0.01);
$this->assertEqualsWithDelta(10.2, $value, 0.1);
$this->assertEquals(10, $value);
$this->assertSame(10, $value);
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\PHPUnit\Transform\AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRector::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

declare(strict_types=1);

namespace Rector\PHPUnit\Transform;

use InvalidArgumentException;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\DNumber;
use Rector\Core\Rector\AbstractRector;
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
use Rector\PHPUnit\NodeFactory\AssertCallFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @see \Rector\PHPUnit\Tests\Transform\Rector\AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRector\AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRectorTest
*/
final class AssertEqualsOrAssertSameFloatParameterToSpecificMethodsTypeRector extends AbstractRector
{
public function __construct(
private readonly AssertCallFactory $assertCallFactory,
private readonly TestsNodeAnalyzer $testsNodeAnalyzer,
) {
}

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Change assertEquals()/assertSame() method using float on expected argument to new specific alternatives.',
[
new CodeSample(
// code before
<<<'CODE_SAMPLE'
$this->assertSame(10.20, $value);
$this->assertEquals(10.20, $value);
$this->assertEquals(10.200, $value);
$this->assertSame(10, $value);
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
$this->assertEqualsWithDelta(10.20, $value, 0.01);
$this->assertEqualsWithDelta(10.20, $value, 0.01);
$this->assertEqualsWithDelta(10.200, $value, 0.001);
$this->assertSame(10, $value);
CODE_SAMPLE
),
]
);
}

/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
}

/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->testsNodeAnalyzer->isPHPUnitMethodCallNames($node, ['assertEquals', 'assertSame'])) {
return null;
}

$args = $node->getArgs();

$firstValue = $args[0]->value;
if (! $firstValue instanceof DNumber) {
return null;
}

$newMethodCall = $this->assertCallFactory->createCallWithName($node, 'assertEqualsWithDelta');
$newMethodCall->args[0] = $args[0];
$newMethodCall->args[1] = $args[1];
$newMethodCall->args[2] = new Arg(new DNumber($this->generateDelta($firstValue)));

return $newMethodCall;
}

private function generateDelta(DNumber $dNumber): float
{
$rawValueNumber = $dNumber->getAttribute('rawValue');
$countDecimals = strrpos((string) $rawValueNumber, '.');

if ($countDecimals === false) {
throw new InvalidArgumentException('First argument passed in the function is not a float.');
}

$countHowManyDecimals = strlen((string) $rawValueNumber) - $countDecimals - 2;

if ($countHowManyDecimals < 1) {
return 0.1;
}

$mountFloat = number_format(0.0, $countHowManyDecimals, '.', '0') . '1';

return (float) $mountFloat;
}
}

0 comments on commit c71ce2a

Please sign in to comment.